Wiki
Tools
Categorie
Help
Una pagina a casoHide minor edits - Show changes to markup
Un'avventura è composta da un'insieme di locazioni, oggetti, pietre miliari e NPC, più un giocatore che gira tra di essi. L'interazione tra le varie componenti del gioco è affidata principalmente agli script scritti in FScript'.
Un'avventura è composta da un'insieme di locazioni, oggetti, pietre miliari e NPC, più un giocatore che gira tra di essi. L'interazione tra le varie componenti del gioco è affidata principalmente agli script scritti in FScript.
Codice sorgente: Attach:babaogluengine-0.1.src.zip
Codice sorgente: babaogluengine-0.1.src.zip
Il Babaoglu Engine è un semplice motore per psuedo giochi di ruolo che si giocano da linea di comando. Ricorda un po' le IF (Interactive Fiction) e i MUD (Multi-User Dungeon) nel tipo di interazione col gioco, solo che non c'è opportunità di multiplayer.
Il Babaoglu Engine è un semplice motore per psuedo giochi di ruolo che si giocano da linea di comando, scritto in Java e rilasciato con licenza GPL. Ricorda un po' le IF (Interactive Fiction) e i MUD (Multi-User Dungeon) nel tipo di interazione col gioco, solo che non c'è opportunità di multiplayer.
Il motore del gioco è scritto in Java, ma il gioco stesso no. Utilizza un linguaggio di script chiamato FScript, che è molto semplice da imparare. Le azioni e le interazioni tra gli oggetti, le locazioni della mappa ed il personaggio avvengono tramite gli script scritti in FScript. Il bello di un sistema del genere è che il motore rimane identico, ma si può cambiare la realtà del gioco intervenendo su questi script, senza bisogno di ricompilare alcunché. Inoltre, la semplicità del linguaggio di script permette la creazione di avventure anche a chi non è programmatore. Un altro vantaggio è che si può separare il gioco dalla sua interfaccia: per ora c'è una semplice GUI, ma non ci vuole molto a scrivere qualcosa di diverso e più appariscente. La grafica non è prevista (niente giochi tipo Monkey Island, per intenderci).
Il motore del gioco è scritto in Java, ma i giochi stessi no. Si utilizza un linguaggio di script chiamato FScript, che è molto semplice da imparare. Le azioni e le interazioni tra gli oggetti, le locazioni della mappa ed il personaggio avvengono tramite gli script scritti in FScript. Il bello di un sistema del genere è che il motore rimane identico, ma si può cambiare la realtà del gioco intervenendo su questi script, senza bisogno di ricompilare alcunché. Inoltre, la semplicità del linguaggio di script permette la creazione di avventure anche a chi non è programmatore. Un altro vantaggio è che si può separare il gioco dalla sua interfaccia: per ora c'è una semplice GUI, ma non ci vuole molto a scrivere qualcosa di diverso e più appariscente. La grafica non è prevista (niente giochi tipo Monkey Island, per intenderci).
Codice sorgente: Attach:babaogluengine-0.1.src.zip
Che fine han fatto i compitini? è un avventura per il Babaoglu Engine.
Nel file leggimi.txt ci sono le istruzioni per giocare.
Ho pronta una demo del Babaoglu Engine, con tanto di un'avventura di prova:)
C'è un file .bat che dovrebbe funzionare sotto winzozz, cmq la sintassi è:
java -jar babaoglu.jar demo
demo è la cartella che contiene i files del gioco. Sono files di testo, quindi guardandoli potrete capire la dinamica della piccola avventura che ho scritto: vi conviene aspettare a farlo, prima giocatela e datemi le vostre impressioni!
Faccio un riassunto dei comandi:
[vai] nord|sud|est|ovest|su|giu: va nella direzione specificata, se possibile. Se esce il messaggio "Tu non puoi passare!" vuol dire semplicemente che quella porta è chiusa. Esempio: vai est, nord.
apri nord|sud|est|ovest|su|giu: apre la porta corrispondente alla direzione selezionata. Attenzione: non sempre è possibile aprire tutte le porte, a volte occorrono chiavi, oppure sono semplicemente porte chiuse del tutto! Inoltre, quando si apre una porta NON si va automaticamente in quella direzione: la sequenza di comandi corretta è, per esempio:
apri nord vai nord
uscite: vi dà una lista delle uscite VISIBILI della locazione in cui vi trovate.
guarda: vi dà una descrizione del posto in cui vi trovate, completa di lista di oggetti, personaggi ed uscite. Attenzione: NON tutte le uscite sono visibili, quindi, può darsi che ci siano uscite che il comando guarda inizialmente non rileva!:) Le direzioni sono sempre le solite: nord, sud, est, ovest, su, giu.
guarda <checosa>: posso guardare oggetti o personaggi. Il gioco rispetta le maiuscole, quindi rispettatele anche voi. Inoltre, i nomi degli oggetti e dei personaggi NON contengono spazi, nei comandi. Esempio: guarda Ceravolo, guarda salame.
parla <personaggio>: parla con un personaggio. Per esempio, parla Ceravolo parlerà con Ceravolo. È anche possibile indicare un argomento di conversazione, ma non tutti i PNG lo possono fare. Di solito, ma non sempre, quando un PNG dice qualcosa in MAIUSCOLO, provate a chiedergli quella cosa. Esempio: se Dario dice una frase come "mi piacciono i GATTI", potete provare a usare il comando "parla Dario gatti". Un po' rozzo, ma per ora è così:) Inoltre, se un personaggio ora non dice niente di interessante, può darsi invece che più in là abbia qualche cosa da dirvi...
prendi <nomeoggetto>: cerca di prendere l'oggetto presente. Non tutti gli oggetti sono trasportabili.
inventario oppure inv: vi dà una lista di ciò che vi portate appresso.
lascia <nomeoggetto>: lascia un oggetto del vostro inventario nel posto in cui vi trovate.
usa <oggetto>: è il comando per interagire con un oggetto. È un po' generico, quindi per ora usa può voler dire fruga o accendi e così via. Più in là vedo di fare qualcosa di più carino.
usa <oggetto> <oggettopassivo>: è un modo per utilizzare un certo oggetto SU di un altro oggetto, detto passivo. Ad esempio, usa martello chiodo cercherà di usare l'oggetto martello con l'oggetto chiodo. Un po' grezzo, ma al solito, siamo agli inizi:)
vai nord|sud|est|ovest|su|giu: va nella direzione specificata, se possibile. Se esce il messaggio "Tu non puoi passare!" vuol dire semplicemente che quella porta è chiusa. Esempio: vai est.
[vai] nord|sud|est|ovest|su|giu: va nella direzione specificata, se possibile. Se esce il messaggio "Tu non puoi passare!" vuol dire semplicemente che quella porta è chiusa. Esempio: vai est, nord.
... TODO ...
Per evitare di salvare tutte le cose che i giocatori dicono assieme agli script, esistono i files .blabla che contengono i discorsi.
Nel file, un discorso è definito così
[nome] testo, con <b>eventuali</b> tag html
I discorsi possono essere richiamati in due modi:
Ad esempio, se ho un oggetto così
[salame] tipo = oggetto descrizione = $salame
il Babaoglu Engine, al comando guarda salame andrà a ripescare il discorso chiamato salame.
Il comando salva serve per salvare l'evoluzione della computazione del gioco. Vi chiederà di fornire un nome di file.
Il comando carica inopinatamente serve per caricare un gioco salvato.
:: Babaoglu Engine ::
Il motore del gioco è scritto in Java, ma il gioco stesso no. Utilizza un linguaggio di script chiamato FScript, che è molto semplice da imparare. Le azioni e le interazioni tra gli oggetti, le locazioni della mappa ed il personaggio avvengono tramite gli script scritti in FScript. Il bello di un sistema del genere è che il motore rimane identico, ma si può cambiare la realtà del gioco intervenendo su questi script, senza bisogno di ricompilare alcunché. Inoltre, la semplicità del linguaggio di script permette la creazione di avventure anche a chi non è programmatore. Un altro vantaggio è che si può separare il gioco dalla sua interfaccia: per ora c'è una semplice GUI, ma non ci vuole molto a scrivere qualcosa di diverso e più apapriscente. La grafica non è prevista (niente giochi tipo Monkey Island, per intenderci).
Il motore del gioco è scritto in Java, ma il gioco stesso no. Utilizza un linguaggio di script chiamato FScript, che è molto semplice da imparare. Le azioni e le interazioni tra gli oggetti, le locazioni della mappa ed il personaggio avvengono tramite gli script scritti in FScript. Il bello di un sistema del genere è che il motore rimane identico, ma si può cambiare la realtà del gioco intervenendo su questi script, senza bisogno di ricompilare alcunché. Inoltre, la semplicità del linguaggio di script permette la creazione di avventure anche a chi non è programmatore. Un altro vantaggio è che si può separare il gioco dalla sua interfaccia: per ora c'è una semplice GUI, ma non ci vuole molto a scrivere qualcosa di diverso e più appariscente. La grafica non è prevista (niente giochi tipo Monkey Island, per intenderci).
Un'avventura è composta da un'insieme di locazioni, oggetti, pietre miliari e NPC, più un giocatore che gira tra di essi. L'interazione tra le varie componenti del gioco è affidata principalmente agli script scritti in FScript'.
Fisicamente le avventure risiedono in diversi files, i quali servono a descrivere le varie componenti dell'avventura.
I files .baba servono per le gli oggetti, gli NPC e le pietre miliari.
I files .loc servono per le locazioni.
I files .script contengono gli script.
I files .blabla contengono i discorsi.
Il file .ini contiene le informazioni necessarie all'avvio del gioco.
Tutti questi files vanno messi in una cartella, e l'indirizzo di quella cartella va passato come parametro al costruttore della classe Gioco. Nella mia implementazione del Babaoglu Engine, si passa l'indirizzo della cartella da linea di comando, e questo verrà successivamente passato al costruttore di Gioco.
[inizio] nomeGiocatore = Dario descrizioneGiocatore = Studente locazioneIniziale = biblio001 titoloFinestra = Gioco di prova per il Babaoglu Engine
Un file .ini deve avere la struttura qui riportata, obbligatoriamente. Tutto il resto viene ignorato.
Il formato dei files .ini viene usato anche per i .baba e i .loc, con un diverso utilizzo dei campi.
... TODO ...
Le locazioni vengono salvate in files con l'estensione .loc, il cui formato è il seguente:
[id_della_locazione] nome = nome della locazione descrizione = descrizione della locazione #uscita dir = id_destinazione aperta visibile uscita nord = id_destinazione true true uscita sud = id_destinazione false false
Le righe che iniziano con # sono considerate commenti.
Per essere valida, una locazione in un file .loc deve avere i campi nome e descrizione.
Un oggetto ha un nome e una descrizione. Il giocatore ha un inventario, che contiene un numero infinito di oggetti (ma sì! chi se ne frega:), e può avere più di una copia di uno stesso oggetto. Oggetti come le chiavi possono essere usate per aprire porte. In generale, il giocatore può usare un oggetto da solo (per esempio, usare una cornamusa per suonare un po') oppure usare un oggetto con un altro oggetto (per esempio, usare una chiave con una porta).
Un oggetto ha un nome e una descrizione. Il giocatore ha un inventario, che contiene un numero infinito di oggetti, e può avere più di una copia di uno stesso oggetto. Oggetti come le chiavi possono essere usate per aprire porte. In generale, il giocatore può usare un oggetto da solo (per esempio, usare una cornamusa per suonare un po') oppure usare un oggetto con un altro oggetto (per esempio, usare una chiave con una porta).
Gli oggetti sono salvati in files con l'estensione .baba. Il formato è simile a quello delle locazioni:
[nome oggetto] tipo = oggetto descrizione = descrizione dell'oggetto
Per essere valido, occorre indicare il campo tipo = oggetto e la descrizione. La riga tipo = oggetto serve per distinguere gli oggetti dagli NPC e dalle Pietre Miliari. Gli altri campi sono ignorati.
Anche le Pietre Miliari sono salvate in files .baba.
[nome pietra miliare] tipo = pietra descrizione = descrizione della pietra miliare
La riga tipo = pietra ed il campo descrizione sono obbligatori. Altri campi saranno ignorati.
In questa sezione sono raccolte le note relative all'implementazione del gioco e degli script.
La Locazione è un oggetto con i seguenti campi:
Lo script di default associato ad una locazione è una funzione FScript dal nome composto così: <id>_func(). Per esempio, se la locazione Biblioteca ha id biblio, la sua funzione di default sarà chiamata biblio_func. Il motore cercherà questa funzione: se esiste, sarà eseguita.
Uscita:
Quando si tenta di aprire una porta con un oggetto, occorre specificarlo nel comando apri. Un'uscita ha una funzione di default associata, di nome <idloc>_<direzione>_func => biblio_nord_func(String cheCosa).
Un oggetto ha una funzione di default associata, di nome <nome_oggetto>_func(String cheCosa). Se l'argomento cheCosa è "niente", si attiva l'azione associata all'oggetto, per esempio suonarlo se è uno strumento musicale. Altrimenti, cheCosa può essere il nome di un altro oggetto presente nell inventario oppure un'uscita della locazione attuale. In questi casi, avverranno le azioni stabilite dallo script.
Solo gli oggetti contrassegnati con mobile possono essere messi in inventario.
Da notare che nella riga di comando il primo argomento è l'oggetto attivo, mentre il secondo è l'oggetto passivo. Ciò vuol dire che una riga di comando come usa accendino carta
chiamerà la funzione carta_funz("accendino") e lo script di carta reagirà di conseguenza.
Una pietra miliare è del tutto simile ad un Oggetto, ed è possibile associarvi una String contenente il testo che verrà comunicato al giocatore in occasione del conseguimento di tale Pietra Miliare.
Anche alle pietre miliari è associata una funzione di default, chiamata <nomepietra>_func. Quando una pietra miliare viene data al player, viene chiamata la funzione <nomepietra>_func con parametro "dai"; quando viene tolta il parametro è "togli".
idLocAttuale è la posizione in cui si trova in un preciso istante. La funzione di default di un PNG si chiama <nome>_func(string azione, string argomento). L'azione è "niente" se si vuole attivare la sequenza normale, oppure può essere "parla" per interagire con il personaggio. L'argomento può essere richiesto, ad esempio, per parlare con l'NPC di uno specifico argomento.
Anche gli NPC sono salvati nei files .baba.
[nome NPC] tipo = NPC descrizione = descrizione dell'NPC proprietà 1 = valore proprietà 2 = valore
La riga tipo = NPC e il campo descrizione sono obbligatori. Gli altri campi sono facoltativi, e possono servire per gestire alcuni aspetti di un'avventura, in quanto sono accessibili via script.
apri <dove> [<oggetto>]
<dove> deve essere un'uscita valida. Se presente l'argomento <oggetto>, si chiamerà lo script dell'uscita con <oggetto> come argomento, e l'oggetto deve essere presente nell'inventario.
apri <dove>
<dove> deve essere un'uscita valida.
chiudi <dove>
<oggetto> deve essere un oggetto presente nella lista di oggetti della locazione attuale.
<oggetto> deve essere un oggetto presente nella locazione attuale.
<oggetto> deve essere un oggetto presente nell'inventario. Se ci sono più copie dell'oggetto, ne viene lasciata 1. L'oggetto lasciato si aggiunge alla lista degli oggetti della locazione corrente.
<oggetto> deve essere un oggetto presente nell'inventario. Se ci sono più copie dell'oggetto, ne viene lasciata 1. L'oggetto lasciato rimane nella locazione corrente.
Gli script sono scritti in FScript, che è un linguaggio piuttosto semplice (forse fin troppo, ma va beh). Si possono associare script a oggetti, locazioni ed uscite di locazione.
Sono letti dai files con estensione .script.
func nomeoggetto_func(String azione, String param) ... ... end func
L'azione è l'azione che si vuol compiere con l'oggetto. È possibile anche passare un parametro, che rappresenta l'oggetto passivo nell'azione. Ecco un esempio:
func coltello_func(string param, string obj) if (param == "usa") if (obj=="") scrivi("Usi il coltello con che cosa? Vuoi farti male?") elsif (obj=="salame") if (inInventario("salame") == 0) scrivi("Mangi il salame... mmm delizioso:)") togliOggetto("salame") endif endif endif endfunc
func idlocazione_func(String param) ... ... endfunc
Vengono eseguiti ogni volta che il giocatore capita in una locazione.
func idlocazione_nomeuscita_func(String param) ... ... endfunc
Vengono chiamati quando si esegue un comando apri o chiudi su di un'uscita. Ecco un esempio:
func biblio001_giu_func(string param) if (inInventario("chiave") == 0) if (param == "apri") apri("biblio001", "giu") scrivi("La botola si apre lentamente...") elsif (param == "chiudi") chiudi("biblio001" , "giu") endif else scrivi("Non hai la chiave...") endif endfunc
Ci sono un po' di chiamate di funzione disponibili all'interno degli script. Servono per recuperare ed impostare i parametri del gioco.
Il gioco è salvato in una cartella, la quale viene passata come argomento al motore del gioco all'avvio. La cartella può contenere un qualsiasi numero di files.
Si assume che i files con estensione .baba
contengano la descrizione di locazioni e oggetti, i files .script
devono contenere gli script, le locazioni siano contenute nei files .loc
.
In questi files, le informazioni vengono codificate secondo un certo schema che presento qui sotto.
Un blocco è composto da un certo numero di righe contenenti definizioni, separate da righe contenenti 4 trattini. Le definizioni sono del tipo:
<nome>=<definizione>
La prima riga del blocco deve contenere il tipo del blocco stesso. Le righe che iniziano per # sono considerate commenti.
tipo=locazione nome=Biblioteca id=biblio01 descrizione=È una sala ampia, dal pavimento di linoleum blu. Le finestre sono grandi, rivolte verso sud. Ci sono diversi tavoli bianchi, e il silenzio regna sovrano #direzione idloc visibilità aperta uscita=nord biblio02 true true uscita=sud corridoio01 true true uscita=est cortile01 true false
tipo=oggetto nome=martello descrizione=Un martello da muratore, col manico lungo e sporco di cemento.
tipo=png nome=Danio descrizione=Un uomo di mezza età, un po' calvo, dal viso tranquillo. idloc=biblio01
Gli script, come spiegato sopra, sono contenuti in funzioni con un nome standard, così da poter essere facilmente rintracciabili.
func biblio01_func(string param) ... ... endfunc func martello_func(string param, string obj) ... ... endfunc func biblio01_nord_func(string param) ... ... endfunc func danio_func(string param, string argomento) ... ... endfunc
In ogni avventura realizzata per il Babaoglu Engine, occorre che sia definita la pietra miliare di nome inizio, e che la sua relativa func presenti almeno queste funzionalità:
func inizio_func(string param) if (param=="getNomePlayer") return "Studente" elsif (param=="getDescrPlayer") return "Un bel bambino" elsif (param=="getLocIniziale") return "biblio001" else scrivi("Benvenuto nella demo del Babaoglu Engine!") endif endfunc
Infatti, inizio_func viene chiamata per inizializzare il gioco.
Esempio: guarda Ceravolo, guarda salame.
Inoltre, se un personaggio ora non dice niente di interessante, può darsi invece che più in là abbia qualche cosa da dirvi...
vai nord|sud|est|ovest|su|giu: va nella direzione specificata, se possibile. Se esce il messaggio "Tu non puoi passare!" vuol dire semplicemente che quella porta è chiusa.
vai nord|sud|est|ovest|su|giu: va nella direzione specificata, se possibile. Se esce il messaggio "Tu non puoi passare!" vuol dire semplicemente che quella porta è chiusa. Esempio: vai est.
parla <personaggio: parla con un personaggio. Per esempio, parla Ceravolo parlerà con Ceravolo.
parla <personaggio>: parla con un personaggio. Per esempio, parla Ceravolo parlerà con Ceravolo.
Ho pronta una demo del Babaoglu Engine, con tanto di un'avventura di prova:)
C'è un file .bat che dovrebbe funzionare sotto winzozz, cmq la sintassi è:
java -jar babaoglu.jar demo
demo è la cartella che contiene i files del gioco. Sono files di testo, quindi guardandoli potrete capire la dinamica della piccola avventura che ho scritto: vi conviene aspettare a farlo, prima giocatela e datemi le vostre impressioni!
Faccio un riassunto dei comandi: vai nord|sud|est|ovest|su|giu: va nella direzione specificata, se possibile. Se esce il messaggio "Tu non puoi passare!" vuol dire semplicemente che quella porta è chiusa.
apri nord|sud|est|ovest|su|giu: apre la porta corrispondente alla direzione selezionata. Attenzione: non sempre è possibile aprire tutte le porte, a volte occorrono chiavi, oppure sono semplicemente porte chiuse del tutto! Inoltre, quando si apre una porta NON si va automaticamente in quella direzione: la sequenza di comandi corretta è, per esempio:
apri nord vai nord
uscite: vi dà una lista delle uscite VISIBILI della locazione in cui vi trovate.
guarda: vi dà una descrizione del posto in cui vi trovate, completa di lista di oggetti, personaggi ed uscite. Attenzione: NON tutte le uscite sono visibili, quindi, può darsi che ci siano uscite che il comando guarda inizialmente non rileva!:) Le direzioni sono sempre le solite: nord, sud, est, ovest, su, giu.
guarda <checosa>: posso guardare oggetti o personaggi. Il gioco rispetta le maiuscole, quindi rispettatele anche voi. Inoltre, i nomi degli oggetti e dei personaggi NON contengono spazi, nei comandi.
parla <personaggio: parla con un personaggio. Per esempio, parla Ceravolo parlerà con Ceravolo. È anche possibile indicare un argomento di conversazione, ma non tutti i PNG lo possono fare. Di solito, ma non sempre, quando un PNG dice qualcosa in MAIUSCOLO, provate a chiedergli quella cosa. Esempio: se Dario dice una frase come "mi piacciono i GATTI", potete provare a usare il comando "parla Dario gatti". Un po' rozzo, ma per ora è così:)
prendi <nomeoggetto>: cerca di prendere l'oggetto presente. Non tutti gli oggetti sono trasportabili.
inventario oppure inv: vi dà una lista di ciò che vi portate appresso.
lascia <nomeoggetto>: lascia un oggetto del vostro inventario nel posto in cui vi trovate.
usa <oggetto>: è il comando per interagire con un oggetto. È un po' generico, quindi per ora usa può voler dire fruga o accendi e così via. Più in là vedo di fare qualcosa di più carino.
usa <oggetto> <oggettopassivo>: è un modo per utilizzare un certo oggetto SU di un altro oggetto, detto passivo. Ad esempio, usa martello chiodo cercherà di usare l'oggetto martello con l'oggetto chiodo. Un po' grezzo, ma al solito, siamo agli inizi:)
[@func biblio01_func(string param)
...
...\\
[@func biblio01_func(string param) ... ...
func martello_func(string param, string obj)
...
...\\
func martello_func(string param, string obj) ... ...
func biblio01_nord_func(string param)
...
...\\
func biblio01_nord_func(string param) ... ...
func danio_func(string param, string argomento)
...
...\\
func danio_func(string param, string argomento) ... ...
[@func biblio01_func()\\
[@func biblio01_func(string param)\\
func martello_func(String cheCosa)\\
func martello_func(string param, string obj)\\
func biblio01_nord_func(String cheCosa)\\
func biblio01_nord_func(string param)\\
func danio_func(String argomento)\\
func danio_func(string param, string argomento)\\
endfunc
endfunc@]
I Personaggi Non Giocanti hanno un nome e una descrizione. L'interazione di un personaggio con un PNG avviene principalmente tramite la parola, attraverso anche il saggio utilizzo delle Pietre Miliari descritte qui sopra. Tramite opportuni script, è possibile far muovere un PNG in giro per la mappa, passando solo per le uscite aperte della locazione in cui si trova, per esempio, oppure semplicemente teletrasportandosi. Possono dare oggetti o toglierli al personaggio, ed elargire Pietre Miliari.
Gli NPC (non-playing characters), o PNG (Personaggi Non Giocanti), hanno un nome e una descrizione. L'interazione di un personaggio con un PNG avviene principalmente tramite la parola, attraverso anche il saggio utilizzo delle Pietre Miliari descritte qui sopra. Tramite opportuni script, è possibile far muovere un PNG in giro per la mappa, passando solo per le uscite aperte della locazione in cui si trova, per esempio, oppure semplicemente teletrasportandosi. Possono dare oggetti o toglierli al personaggio, ed elargire Pietre Miliari.
Scrive la lista degli oggetti in inventario.
Scrive la lista degli oggetti in inventario. Abbreviata con inv.
uscite
Scrive la lista delle uscite visibili di quella locazione.
descrizione=È una sala ampia, dal pavimento di linoleum blu. Le finestre sono grandi, rivolte verso sud . Ci sono diversi tavoli bianchi, e il silenzio regna sovrano
uscita=nord 1 1 uscita=sud 1 1 uscita=est 0 1
descrizione=È una sala ampia, dal pavimento di linoleum blu.
Le finestre sono grandi, rivolte verso sud. Ci sono diversi tavoli bianchi, e il silenzio regna sovrano
uscita=nord biblio02 true true uscita=sud corridoio01 true true uscita=est cortile01 true false
In ogni avventura realizzata per il Babaoglu Engine, occorre che sia definita la pietra miliare di nome inizio, e che la sua relativa func presenti almeno queste funzionalità:
func inizio_func(string param) if (param=="getNomePlayer") return "Studente" elsif (param=="getDescrPlayer") return "Un bel bambino" elsif (param=="getLocIniziale") return "biblio001" else scrivi("Benvenuto nella demo del Babaoglu Engine!") endif endfunc
Infatti, inizio_func viene chiamata per inizializzare il gioco.
Il motore del gioco è scritto in Java, ma il gioco stesso no. Utilizza un linguaggio di script chiamato FScript, che è molto semplice da imparare. Le azioni e le interazioni tra gli oggetti, le locazioni della mappa ed il personaggio avvengono tramite gli script scritti in FScript. Il bello di un sistema del genere è che il motore rimane identico, ma si può cambiare la realtà del gioco intervenendo su questi script, senza bisogno di ricompilare alcunché. Inoltre, la semplicità del linguaggio di script permette la creazione di avventure anche a chi non è programmatore. Un altro vantaggio è che si può separare il gioco dalla sua interfaccia: per ora c'è una semplice GUI, ma non ci vuole molto a scrivere qualcosa di diverso e più apapriscente. La grafica non è prevista (niente giochi tipo Monkey Island, per intenderci).
Il motore del gioco è scritto in Java, ma il gioco stesso no. Utilizza un linguaggio di script chiamato FScript, che è molto semplice da imparare. Le azioni e le interazioni tra gli oggetti, le locazioni della mappa ed il personaggio avvengono tramite gli script scritti in FScript. Il bello di un sistema del genere è che il motore rimane identico, ma si può cambiare la realtà del gioco intervenendo su questi script, senza bisogno di ricompilare alcunché. Inoltre, la semplicità del linguaggio di script permette la creazione di avventure anche a chi non è programmatore. Un altro vantaggio è che si può separare il gioco dalla sua interfaccia: per ora c'è una semplice GUI, ma non ci vuole molto a scrivere qualcosa di diverso e più apapriscente. La grafica non è prevista (niente giochi tipo Monkey Island, per intenderci).
idLocAttuale è la posizione in cui si trova in un preciso istante. La funzione di default di un PNG si chiama <nome>_func(String argomento). L'argomento è "niente" se si vuole attivare la sequenza normale, oppure può essere "parla" per interagire con il personaggio.
idLocAttuale è la posizione in cui si trova in un preciso istante. La funzione di default di un PNG si chiama <nome>_func(string azione, string argomento). L'azione è "niente" se si vuole attivare la sequenza normale, oppure può essere "parla" per interagire con il personaggio. L'argomento può essere richiesto, ad esempio, per parlare con l'NPC di uno specifico argomento.
Il motore del gioco è scritto in Java, ma il gioco stesso no. Utilizza un linguaggio di script chiamato FScript, che è molto semplice da imparare. Le azioni e le interazioni tra gli oggetti, le locazioni della mappa ed il personaggio avvengono tramite gli script scritti in FScript. Il bello di un sistema del genere è che il motore rimane identico, ma si può cambiare la realtà del gioco intervenendo su questi script, senza bisogno di ricompilare alcunché. Inoltre, la semplicità del linguaggio di script permette la creazione di avventure anche a chi non è programmatore. Un altro vantaggio è che si può separare il gioco dalla sua interfaccia: per ora è a linea di comando, ma non occorre cambiare nulla per portare il tutto dentro a una semplice GUI. La grafica non è prevista (niente giochi tipo Monkey Island, per intenderci).
Il motore del gioco è scritto in Java, ma il gioco stesso no. Utilizza un linguaggio di script chiamato FScript, che è molto semplice da imparare. Le azioni e le interazioni tra gli oggetti, le locazioni della mappa ed il personaggio avvengono tramite gli script scritti in FScript. Il bello di un sistema del genere è che il motore rimane identico, ma si può cambiare la realtà del gioco intervenendo su questi script, senza bisogno di ricompilare alcunché. Inoltre, la semplicità del linguaggio di script permette la creazione di avventure anche a chi non è programmatore. Un altro vantaggio è che si può separare il gioco dalla sua interfaccia: per ora c'è una semplice GUI, ma non ci vuole molto a scrivere qualcosa di diverso e più apapriscente. La grafica non è prevista (niente giochi tipo Monkey Island, per intenderci).
Anche alle pietre miliari è associata una funzione di default, chiamata <nomepietra>_func.
Anche alle pietre miliari è associata una funzione di default, chiamata <nomepietra>_func. Quando una pietra miliare viene data al player, viene chiamata la funzione <nomepietra>_func con parametro "dai"; quando viene tolta il parametro è "togli".
Si assume che i files con estensione .oglu
contengano la descrizione di locazioni e oggetti, mentre i files .script
devono contenere gli script.
Si assume che i files con estensione .baba
contengano la descrizione di locazioni e oggetti, i files .script
devono contenere gli script, le locazioni siano contenute nei files .loc
.
<nome>::=<definizione>
<nome>=<definizione>
[@tipo::=locazione nome::=Biblioteca id::=biblio01 descrizione::=È una sala ampia, dal pavimento di linoleum blu. Le finestre sono grandi, rivolte verso sud
[@tipo=locazione nome=Biblioteca id=biblio01 descrizione=È una sala ampia, dal pavimento di linoleum blu. Le finestre sono grandi, rivolte verso sud
uscita::=nord 1 1 uscita::=sud 1 1 uscita::=est 0 1
uscita=nord 1 1 uscita=sud 1 1 uscita=est 0 1
[@tipo::=oggetto nome::=martello descrizione::=Un martello da muratore, col manico lungo e sporco di cemento.
[@tipo=oggetto nome=martello descrizione=Un martello da muratore, col manico lungo e sporco di cemento.
tipo::=png nome::=Danio descrizione::=Un uomo di mezza età, un po' calvo, dal viso tranquillo. idloc::=biblio01
tipo=png nome=Danio descrizione=Un uomo di mezza età, un po' calvo, dal viso tranquillo. idloc=biblio01
Una pietra miliare è del tutto simile ad un Oggetto, ed è possibile associarvi una String contenente il testo che verrà comunicato al giocatore in occasione del conseguimento di tale Pietra Miliare.
Anche alle pietre miliari è associata una funzione di default, chiamata <nomepietra>_func.
endfunc
[@func biblio01_func() ... ...
[@func biblio01_func()
...
...\\
func martello_func(String cheCosa) ... ...
func martello_func(String cheCosa)
...
...\\
func biblio01_nord_func(String cheCosa) ... ...
func biblio01_nord_func(String cheCosa)
...
...\\
func danio_func(String argomento) ... ...
func danio_func(String argomento)
...
...\\
idLocAttuale è la posizione in cui si trova in un preciso istante. La funzione di default di un PNG si chiama <nome>_funz(String argomento). L'argomento è "niente" se si vuole attivare la sequenza normale, oppure può essere "parla" per interagire con il personaggio.
idLocAttuale è la posizione in cui si trova in un preciso istante. La funzione di default di un PNG si chiama <nome>_func(String argomento). L'argomento è "niente" se si vuole attivare la sequenza normale, oppure può essere "parla" per interagire con il personaggio.
tipo::=png nome::=Danio descrizione::=Un uomo di mezza età, un po' calvo, dal viso tranquillo. idloc::=biblio01
func martello_func(String oggetto)
func martello_func(String cheCosa)
func biblio01_nord(String oggetto)
func biblio01_nord_func(String cheCosa) ... ... endfunc
func danio_func(String argomento)
Quando si tenta di aprire una porta con un oggetto, occorre specificarlo nel comando apri. Un'uscita ha una funzione di default associata, di nome <idloc>_<direzione>_func => biblio_nord_func().
Quando si tenta di aprire una porta con un oggetto, occorre specificarlo nel comando apri. Un'uscita ha una funzione di default associata, di nome <idloc>_<direzione>_func => biblio_nord_func(String cheCosa).
Un oggetto ha una funzione di default associata, di nome <nome_oggetto>_funz(String cheCosa). Se l'argomento cheCosa è "niente", si attiva l'azione associata all'oggetto, per esempio suonarlo se è uno strumento musicale. Altrimenti, cheCosa può essere il nome di un altro oggetto presente nell inventario oppure un'uscita della locazione attuale. In questi casi, avverranno le azioni stabilite dallo script.
Un oggetto ha una funzione di default associata, di nome <nome_oggetto>_func(String cheCosa). Se l'argomento cheCosa è "niente", si attiva l'azione associata all'oggetto, per esempio suonarlo se è uno strumento musicale. Altrimenti, cheCosa può essere il nome di un altro oggetto presente nell inventario oppure un'uscita della locazione attuale. In questi casi, avverranno le azioni stabilite dallo script.
descrizione::=È una sala ampia, dal pavimento di linoleum blu. Le finestre sono grandi, rivolte verso sud. Ci sono diversi tavoli bianchi, e il silenzio regna sovrano
descrizione::=È una sala ampia, dal pavimento di linoleum blu. Le finestre sono grandi, rivolte verso sud . Ci sono diversi tavoli bianchi, e il silenzio regna sovrano
Gli script, come spiegato sopra, sono contenuti in funzioni con un nome standard, così da poter essere facilmente rintracciabili.
Gli script, come spiegato sopra, sono contenuti in funzioni con un nome standard, così da poter essere facilmente rintracciabili.
[@func biblio01_func() ... ... endfunc
func martello_func(String oggetto) ... ... endfunc
func biblio01_nord(String oggetto) ... ... endfunc
tipo::=locazione
[@tipo::=locazione
uscita::=nord 0
uscita::=nord 1 1 uscita::=sud 1 1 uscita::=est 0 1 @]
[@tipo::=oggetto nome::=martello descrizione::=Un martello da muratore, col manico lungo e sporco di cemento.
Gli script, come spiegato sopra, sono contenuti in funzioni con un nome standard, così da poter essere facilmente rintracciabili.
Il gioco è salvato in una cartella, la quale viene passata come argomento al motore del gioco all'avvio. La cartella può contenere un qualsiasi numero di files.
Si assume che i files con estensione .oglu
contengano la descrizione di locazioni e oggetti, mentre i files .script
devono contenere gli script.
In questi files, le informazioni vengono codificate secondo un certo schema che presento qui sotto.
Un blocco è composto da un certo numero di righe contenenti definizioni, separate da righe contenenti 4 trattini. Le definizioni sono del tipo:
<nome>::=<definizione>
La prima riga del blocco deve contenere il tipo del blocco stesso. Le righe che iniziano per # sono considerate commenti.
tipo::=locazione nome::=Biblioteca id::=biblio01 descrizione::=È una sala ampia, dal pavimento di linoleum blu. Le finestre sono grandi, rivolte verso sud. Ci sono diversi tavoli bianchi, e il silenzio regna sovrano
uscita::=nord 0
La chiave è l'oggetto per aprirla. Quando si tenta di aprire una porta con un oggetto, occorre specificarlo. Un'uscita ha una funzione di default associata, di nome <idloc>_<direzione>_func => biblio_nord_func().
Quando si tenta di aprire una porta con un oggetto, occorre specificarlo nel comando apri. Un'uscita ha una funzione di default associata, di nome <idloc>_<direzione>_func => biblio_nord_func().
Solo gli oggetti contrassegnati con mobile possono essere messi in inventario.
<dove> deve essere un'uscita valida. Se presente l'argomento <oggetto>, si chiamerà lo script dell'uscita con <oggetto> come argomento.
<dove> deve essere un'uscita valida. Se presente l'argomento <oggetto>, si chiamerà lo script dell'uscita con <oggetto> come argomento, e l'oggetto deve essere presente nell'inventario.
usa <oggetto_attivo> <oggetto_passivo>
L'oggetto attivo
L'<oggetto_attivo> può essere nell'inventario oppure presente nella lista degli oggetti della locazione attuale. L'<oggetto_passivo> può essere nell'inventario o nella locazione.
Le locazioni sono i vari punti della mappa del gioco in cui il giocatore, gli oggetti e i PNG o NPC (personaggi non giocanti) si possono trovare.
Una locazione fondamentalmente ha un nome e un id (per essere trovata in modo univoco dagli script) e delle uscite. Le uscite possono essere in una delle direzioni note (nord, est, sud, ovest, su, giu, e magari anche quelle intermedie come nordest e così via). Ogni uscita può essere visibile o invisibile. Inoltre, una particolare uscita può essere aperta o chiusa, e la sua apertura può dipendere dall'interazione di un oggetto con essa. Ciò vuol dire che il player può dover trovare una chiave per poter andare in cantina, per esempio.
Ad ogni locazione è possibile associare uno script. Quello script verrà eseguito ogniqualvolta il giocatore finirà in una locazione. Per esempio, se entro in cantina la prima volta, posso sbattere la testa. La seconda volta starò attento e non lo farò più. Oppure, se entro in un tempio con un amuleto cthulhesco, potrei causare un crollo e restarci secco.
Un oggetto ha un nome e una descrizione. Il giocatore ha un inventario, che contiene un numero infinito di oggetti (ma sì! chi se ne frega:), e può avere più di una copia di uno stesso oggetto. Oggetti come le chiavi possono essere usate per aprire porte. In generale, il giocatore può usare un oggetto da solo (per esempio, usare una cornamusa per suonare un po') oppure usare un oggetto con un altro oggetto (per esempio, usare una chiave con una porta).
Sono come oggetti, ma non rappresentano entità fisiche, bensì dei punti di svolta che il giocatore ha raggiunto nella trama del gioco. Per esempio, se salvo una principessa, avrò una pietra miliare "Salvata la principessa" e quando parlerò al re suo padre, egli lo saprà e mi darà dei soldi, assieme ad una pietra miliare chiamata "Ricevuta ricompensa". Se parlo al re un'altra volta ancora, egli mi ringrazierà ma non mi darà più dei soldi, perché la pietra miliare "Ricevuta ricompensa" attesterà che l'ho già fatto. Qui si intravede bene la potenza degli script...
I Personaggi Non Giocanti hanno un nome e una descrizione. L'interazione di un personaggio con un PNG avviene principalmente tramite la parola, attraverso anche il saggio utilizzo delle Pietre Miliari descritte qui sopra. Tramite opportuni script, è possibile far muovere un PNG in giro per la mappa, passando solo per le uscite aperte della locazione in cui si trova, per esempio, oppure semplicemente teletrasportandosi. Possono dare oggetti o toglierli al personaggio, ed elargire Pietre Miliari.
Parlare con un PNG significa anche porgli delle domande. Lo script associato al PNG mi dirà quali domande posso fargli, e in base a ciò che gli chiederò otterrò le opportune risposte.
In questa sezione sono raccolte le note relative all'implementazione del gioco e degli script.
La Locazione è un oggetto con i seguenti campi:
Lo script di default associato ad una locazione è una funzione FScript dal nome composto così: <id>_func(). Per esempio, se la locazione Biblioteca ha id biblio, la sua funzione di default sarà chiamata biblio_func. Il motore cercherà questa funzione: se esiste, sarà eseguita.
Uscita:
La chiave è l'oggetto per aprirla. Quando si tenta di aprire una porta con un oggetto, occorre specificarlo. Un'uscita ha una funzione di default associata, di nome <idloc>_<direzione>_func => biblio_nord_func().
Un oggetto ha una funzione di default associata, di nome <nome_oggetto>_funz(String cheCosa). Se l'argomento cheCosa è "niente", si attiva l'azione associata all'oggetto, per esempio suonarlo se è uno strumento musicale. Altrimenti, cheCosa può essere il nome di un altro oggetto presente nell inventario oppure un'uscita della locazione attuale. In questi casi, avverranno le azioni stabilite dallo script.
Da notare che nella riga di comando il primo argomento è l'oggetto attivo, mentre il secondo è l'oggetto passivo. Ciò vuol dire che una riga di comando come usa accendino carta
chiamerà la funzione carta_funz("accendino") e lo script di carta reagirà di conseguenza.
idLocAttuale è la posizione in cui si trova in un preciso istante. La funzione di default di un PNG si chiama <nome>_funz(String argomento). L'argomento è "niente" se si vuole attivare la sequenza normale, oppure può essere "parla" per interagire con il personaggio.
vai <dove>
<dove> deve essere un'uscita valida. Il comando è eseguito solo se la porta è aperta e non ci sono controindicazioni al passaggio (indicate dallo script associato alla porta). Un'uscita invisibile diventa visibile dopo che la si è trovata.
apri <dove> [<oggetto>]
<dove> deve essere un'uscita valida. Se presente l'argomento <oggetto>, si chiamerà lo script dell'uscita con <oggetto> come argomento.
prendi <oggetto>
<oggetto> deve essere un oggetto presente nella lista di oggetti della locazione attuale.
lascia <oggetto>
<oggetto> deve essere un oggetto presente nell'inventario. Se ci sono più copie dell'oggetto, ne viene lasciata 1. L'oggetto lasciato si aggiunge alla lista degli oggetti della locazione corrente.
inventario
Scrive la lista degli oggetti in inventario.
guarda <oggetto>|<personaggio>
L'ordine di analisi è il seguente: se <oggetto> è un oggetto valido, lo si cerca prima nell'inventario, e se non c'è tra gli oggetti presenti nella locazione. Altrimenti, si controlla se si tratta di un nome valido di personaggio, e se quel personaggio si trova attualmente nella locazione in cui si trova il player.
Quando si trova un caso positivo, viene visualizzata la descrizione dell'oggetto o del personaggio.
usa <oggetto_attivo> [<oggetto_passivo>]
usa <oggetto_attivo> <oggetto_passivo>
L'oggetto attivo
(:title Babaoglu Engine:)
:: Babaoglu Engine ::
Il Babaoglu Engine è un semplice motore per psuedo giochi di ruolo che si giocano da linea di comando. Ricorda un po' le IF (Interactive Fiction) e i MUD (Multi-User Dungeon) nel tipo di interazione col gioco, solo che non c'è opportunità di multiplayer.
Serve per poter scrivere delle avventure in cui il giocatore si muove qua e là per una mappa, incontrando persone, raccogliendo e utilizzando oggetti. Non è previsto (per ora) il combattimento.
Il motore del gioco è scritto in Java, ma il gioco stesso no. Utilizza un linguaggio di script chiamato FScript, che è molto semplice da imparare. Le azioni e le interazioni tra gli oggetti, le locazioni della mappa ed il personaggio avvengono tramite gli script scritti in FScript. Il bello di un sistema del genere è che il motore rimane identico, ma si può cambiare la realtà del gioco intervenendo su questi script, senza bisogno di ricompilare alcunché. Inoltre, la semplicità del linguaggio di script permette la creazione di avventure anche a chi non è programmatore. Un altro vantaggio è che si può separare il gioco dalla sua interfaccia: per ora è a linea di comando, ma non occorre cambiare nulla per portare il tutto dentro a una semplice GUI. La grafica non è prevista (niente giochi tipo Monkey Island, per intenderci).