Newsgroup: it.comp.giochi.avventure.testuali
Titolo: [Inform] Azioni tra Before e After

Ciao amici.
Una considerazione tecnica che vorrei sottoporre ai colleghi sviluppatori
Inform.
Nella realizzazione della mia avventura mi sono imbattutto spesso in una
situazione che mi ha creato qualche fastidio: il meccanismo del Before/After per
le Action del gruppo 2 prevede che in fase di After la libreria abbia effettuato
gli eventuali controlli di "eseguibilità" dell'azione richiesta (oggetto
raggiungibile, visibile, toccabile, ecc.) e che il world model sia stato
modificato di conseguenza. La fase di Before viene invece eseguita
immediatamente, prima ancora dei controlli di eseguibilità. Questo secondo me è
limitante, nel senso che mi è capitato diverse volte di sentire la necessità di
un terzo stato, in cui l'azione non viene eseguita (ovverosia il world model non
viene influenzato), ma il controllo di eseguibilità viene comunque effettuato
per coerenza.
Esempio: supponiamo un carillon magico che in una data fase di gioco non può
essere aperto. Il carillon si trova all'interno di una teca chiusa e
trasparente.
Al tentativo di apertura del carillon deve seguire un messaggio del tipo "una
forza invisibile ti impedisce di aprirlo". Tipico comportamento da Before.
Ma il carillon si trova all'interno di un contenitore chiuso, dunque la mia
routine in fase di Before stamperebbe il messaggio anche se, in realtà, il
carillon non è raggiungibile, ovverosia prima di aprire la teca.
Le alternative sono:
ripetere manualmente tutti i controlli di raggiungibilità effettuati da OpenSub,
con grande ridondanza di codice e profonda ineleganza, oppure passare la routine
alla fase di After, il che però implica che quando il controllo di
raggiungibilità verrà effettuato, il carillon sarà già stato formalmente aperto
e quindi sarà necessario richiuderlo via codice prima di stampare il messaggio
di diniego.
Quest'ultima soluzione, pur se inelegante, potrebbe anche essere accettabile
tranne nei casi in cui la modifica del world model modifica l'ordine di un
oggetto in una lista: in questo caso, rimetterlo a posto per fingere la mancata
esecuzione potrebbe modificare l'ordinamento in fase di visualizzazione e dare
effetti sgradevoli.
Qualcuno dirà che in questo caso il controllo di raggiungibilità da ripetere in
fase di Before è banale e coinvolge la verifica dell'apertura della teca; in
questo caso è vero, ma in generale potete verificare che i controlli di
effettuabilità delle Action sono complessi e assumere una loro semplificazione
può essere pericoloso e portare a bug difficili da scoprire.
Quello che servirebbe è un aggancio tra il Before e l'After, dove i controlli di
effettuabilità sono stati effettuati, ma il world model non è ancora stato
alterato.
Io già iniziavo a pensare ad un hack, che però mi pare tutt'altro che banale ma
non impossibile.
Voi che ne dite?
PaoloM

  banale ma non impossibile.
mmmh non puoi mettere un before sul carillon che rimappa "apri carillon"
su "apri teca" finché il carillon è nella teca?
non ci ho pensato su più di qualche istante, per cui forse ci sono
problemi, ma come orientamento io vedrei bene la generazione di azioni
secondarie, che in passato mi sono state molto utili... una roba del
genere (anche se il caso ovviamente è diverso)
Object machine "strange-looking machine" Lab
...
		     before [;  SwitchOn: <<SwitchOn switch>>;
			            SwitchOff: <<SwitchOff switch>>; ...
Object switch "switch" machine
          with name "power" "switch",
...
ciao
S

Scrivevo nel libro di Riven quando Paolo Maroncelli mi interruppe dicendo:
 > Voi che ne dite?
Non conosco bene Inform, ma non č possibile fare sě che quando la teca č 
chiusa l'oggetto carillon sia diverso dall'oggetto carillon quando la teca č 
aperta?
-- 
Atrus di Myst
http://cube.auroraproject.net
 

 Inform.
Una react_after sulla teca dovrebbe bastare. In realtà lo stage after 
per le azioni del gruppo 2 è molto più complesso di quello che sembra e 
ti dovrebbe permettere di intervenire sul gioco nel modo da te voluto. 
Lo stage After è fatto così:
1. Esecuzione di react_after per tutti gli oggetti in scope, incluso 
l'oggetto player (nel tuo esempio potresti definire un react_after per 
la teca)
2. esecuzione di after della stanza
3. esecuzione di after dell'oggetto dell'azione (nel tuo esempio il 
carillon)
4. esecuzione di GamePostRoutine se hai definito questa funzione
La cosa è analoga per lo stage before (con la react_before). Cfr. 
comunque il DM4 perché sono andato a memoria. Per me ti basta questo, 
senza hack.
HAPPY INFORMING!
Giovanni

ti dovrebbe permettere di intervenire sul gioco nel modo da te voluto. 
Sì, la tua soluzione è accettabile ma sposta il comportamento del carillon sulla
teca, il che è formalmente incongruente. Il carillon potrebbe essere ora in una
teca, dopo in un altro contenitore, o magari in mano a qualcuno che di certo non
me lo farà toccare. In tutti questi casi si dovrebbe spostare la logica del
carrillon da un'altra parte, cosa che stilisticamente non mi piace.
Ho letto anche gli altri interventi e gli spunti sono buoni, ma soffrono tutti
di un vizio di fondo: legano un oggetto ad un altro e non consentono di rendere
il comportamento del carillon indipendente. Certo, nulla vieta di fare in modo
che l'Open specificato in fase di Before per il carillon rilevi automaticamente
se lo stesso sia in un contenitore, deviando così l'azione. Ma si tratta sempre
di casi particolari, mentre io volevo ricondurre tutto ad un discorso più
generico.
Da qui, la necessità di un before "esteso" che scatti solo dopo il controllo di
eseguibilità di ogni Action. Sarebbe un hack invasivo, nel senso che
implicherebbe una modifica di ogni Sub routine, ma non difficile da effettuare.
Grazie a tutti,
PaoloM

 per coerenza. [...]
Esiste una libreria alternativa per Inform, Platypus, che potrebbe 
risolvere questo problema. Copioincollo dal tutoriale:
"+respond()+ and +meddle()+ are called immediately before an action 
takes place, but after the library has determined that the action is 
possible.
+respond()+ is called for the direct (=noun=) and +respond_indirect()+ 
for the indirect object (=second=) of the action, and +meddle()+ is 
called for every object in scope."
Non so pero' se sia aggiornata, se sia bi-platform e tutto il resto. E 
il fatto che non sia praticamente stata usata da nessuno se non 
dall'autore potrebbe far pensare che nasconda altre magagne (ma forse 
anche no).
bye
-- 
Paolo Lucchesi
email: plucchesiNOSPAM(at)NOSPAMtin(dot)NOSPAMit
homepage: 
http://www.paololucchesi.it
"Non viviamo in un mondo perfetto (per fortuna)"

 implicherebbe una modifica di ogni Sub routine, ma non difficile da effettuare.
A prescindere dalla soluzione che adotterai, mostraci questo hack che 
magari ci facciamo un'idea migliore di quello che vuoi ottenere.
HAPPY INFORMING!
Giovanni

possible.
A occhio direi che č proprio il comportamento che descrivo.
Grazie per la dritta. Controllerň.
PaoloM

A proposito della questione su Before che avevo sollevato qualche tempo fa,
giusto per dovere di cronaca vi riporto l'estratto di un messaggio apparso su
RAIF che sottolinea ed evidenzia il problema che avevo esposto. L'autore fa
riferimento ad I7 dove pare ci sia la possibilità di intervenire in altro modo
(Instead), oltre alle fasi di Before e After note agli sviluppatore I6. Oggi son
pigro e l'estratto è in inglese.
PaoloM
---------------------------------------
Before rules are carried out before anything else. Specifically,
visibility and touchability are not considered yet when a Before
rule is considered.  Instead rules take place specifically right
after touchabilty and visibility have been decided, but before
any check rules.
See the diagram in 11.2.
So it seems to me that Before rules won't be the right choice
very often, particularly when visibility and touchability will be
a common issue in your game. If there are transparent containers,
darkness, or weird visibility rules, then liberally using Before
seems likely cause bugs.
To critique an example in the documentation:
 Before taking the napkin, say "(first unfolding its delicate
 origami swan)".
This a bug when the napkin is not visible, and perhaps misleading
when its not touchable.
  You are in the dining hall. The long dining table extends from
  end to end.
  Resting on the table, underneath a glass cover, is a napkin,
  folded cleverly into the shape of a swan.
  >TAKE NAPKIN
  (first unfolding its delicate origami swan)
  The glass cover is in the way.
Using an instead rule:
Instead of taking the napkin: say "(first unfolding its delicate
origami swan)"; continue the action.
  >TAKE NAPKIN
  The glass cover is in the way.
  >TAKE GLASS COVER
  Taken.
  >TAKE NAPKIN
  (first unfolding its delicate origami swan)
  Taken.
Anyhow, even if you don't agree the Before rule is a bug, this
still demonstrates the major difference between Before and
Instead rules.