~ubuntu-branches/ubuntu/vivid/inform/vivid

« back to all changes in this revision

Viewing changes to html/section28.html

  • Committer: Bazaar Package Importer
  • Author(s): Jan Christoph Nordholz
  • Date: 2008-05-26 22:09:44 UTC
  • mfrom: (2.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080526220944-ba7phz0d1k4vo7wx
Tags: 6.31.1+dfsg-1
* Remove a considerable number of files from the package
  due to unacceptable licensing terms.
* Repair library symlinks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<HTML><HEAD><TITLE>Section 28: Scope and what you can see</TITLE></HEAD>
2
 
<BODY BGCOLOR="#FFFFFF">
3
 
<TABLE><P>
4
 
<TR><TD Valign="top"><A HREF="contents.html">Contents</A><BR><A HREF="section27.html">Back</A><BR><A HREF="section29.html">Forward</A><TD bgcolor="#F5DEB3"><BLOCKQUOTE><H3>28. Scope and what you can see</H3></BLOCKQUOTE><TR><TD><TD>
5
 
<P>
6
 
 
7
 
<BLOCKQUOTE>
8
 
He cannot see beyond his own nose.  Even the fingers he outstretches
9
 
from it to the world are (as I shall suggest) often invisible to him.
10
 
<P>...Max Beerbohm (<B>1872</B>--<B>1956</B>), of George Bernard Shaw</BLOCKQUOTE>
11
 
<BLOCKQUOTE>
12
 
<BR>Wherefore are these things hid?
13
 
<BR><P>...William Shakespeare (<B>1564</B>--<B>1616</B>), <I>Twelfth Night</I></BLOCKQUOTE>
14
 
<P>
15
 
 
16
 
 
17
 
Time to say what "in scope" means.  This definition is one of the most
18
 
important rules of play, because it decides what the player is allowed
19
 
to refer to.  You can investigate this in practice by compiling any game
20
 
with the debugging suite of verbs included and typing "scope'' in
21
 
different places: but here are the rules in full.  The following are in
22
 
scope:
23
 
<BLOCKQUOTE>
24
 
the player's immediate possessions;<BR>
25
 
the 12 compass directions;<BR>
26
 
if there is light (see <A HREF="section17.html">Section 17</A>), the objects in the same 'enclosure'
27
 
as the player;<BR>
28
 
if not, any objects in the <TT>thedark</TT> object;
29
 
if the player is inside a dark <TT>container</TT>, then that container.<BR>
30
 
</BLOCKQUOTE>
31
 
 
32
 
The 'enclosure' of the player is usually the current location.  Formally,
33
 
it's the outermost object containing the player which remains visible --
34
 
for instance, if the player is in a transparent cabinet in a closed,
35
 
huge cupboard in the Stores Room, then the enclosure is the huge cupboard.
36
 
(Thus items in the huge cupboard are in scope, subject to the remaining
37
 
rules, but other items in the Stores Room are not.)
38
 
<P>
39
 
 
40
 
In addition, if an object is in scope then its immediate
41
 
possessions are in scope, <B> if</B> it is 'see-through', which means that:
42
 
<BLOCKQUOTE>
43
 
the object has <TT>supporter</TT>, <B> or</B><BR>
44
 
the object has <TT>transparent</TT>, <B> or</B><BR>
45
 
the object is an <TT>open</TT> <TT>container</TT>.<BR>
46
 
</BLOCKQUOTE>
47
 
 
48
 
In addition, if an object is in scope then anything which
49
 
it "adds to scope'' is also in scope.
50
 
<P>
51
 
<P>
52
 
 
53
 
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL> The player's possessions are in scope in a dark room -- so the
54
 
player can still turn his lamp on.  On the other hand, a player who
55
 
puts the lamp on the ground and turns it off then loses the ability to
56
 
turn it back on again, because it is out of scope.  This can be changed;
57
 
see below.
58
 
</SMALL>
59
 
<TR><TD><TD><P>
60
 
 
61
 
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL> Compass directions make sense as things.  The player can
62
 
always type something like "attack the south wall'' and the <TT>before</TT> rule
63
 
for the room could trap the action <TT>Attack s_obj</TT> to make something unusual
64
 
happen, if this is desired.
65
 
</SMALL>
66
 
<TR><TD><TD><P>
67
 
 
68
 
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL> The parser applies scope rules to all actors, not just the
69
 
player.  Thus "dwarf, drop sword'' will be accepted if the dwarf can
70
 
see it, even if the player can't.
71
 
</SMALL>
72
 
<TR><TD><TD><P>
73
 
 
74
 
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL> The <TT>concealed</TT> attribute only hides objects from room
75
 
descriptions, and doesn't remove them from scope.  If you want things to
76
 
be both concealed and unreferrable-to, put them somewhere else!  Or
77
 
give them an uncooperative <TT>parse_name</TT> routine.
78
 
</SMALL>
79
 
<TR><TD><TD><P>
80
 
 
81
 
<P><TR><TD Valign="top"><IMG SRC="icons/ddbend.gif" ALT="/\/\"><TD bgcolor="#EEEEEE"><SMALL> Actually, the above definition is not quite right, because
82
 
the compass directions are not in scope when the player asks for a plural
83
 
number of things, like "take all the knives"; this makes some of the
84
 
parser's plural algorithms run faster.  Also, for a <TABLE Border><TR><TD><TT>multiexcept</TT></TABLE>
85
 
token, the other object is not in scope; and for a <TABLE Border><TR><TD><TT>multiinside</TT></TABLE> token,
86
 
only objects in the other object are in scope.  This makes "take everything
87
 
from the cupboard'' work in the natural way.
88
 
<P>
89
 
</SMALL>
90
 
<TR><TD><TD><P>
91
 
 
92
 
 
93
 
Two library routines are provided to enable you to see what's in
94
 
scope and what isn't.  The first, <TT>TestScope(obj, actor)</TT>, simply returns
95
 
true or false according to whether or not <TT>obj</TT> is in scope.  The
96
 
second is <TT>LoopOverScope(routine, actor)</TT> and calls the given routine
97
 
for each object in scope.  In each case the <TT>actor</TT> given is optional;
98
 
if it's omitted, scope is worked out for the player as
99
 
usual.
100
 
<P>
101
 
 
102
 
<P><TR><TD Valign="top"><IMG SRC="icons/exercise.gif" ALT="??"><TD bgcolor="#FBB9AC"><A NAME="ex79"><B>EXERCISE 79:</B><BR>(link to <A HREF="answers2/answer79.html">the answer</A>)<TR><TD><TD>  Implement the debugging suite's "scope'' verb,
103
 
which lists all the objects currently in
104
 
scope.
105
 
<P>
106
 
 
107
 
<P><TR><TD Valign="top"><IMG SRC="icons/exercise.gif" ALT="??"><TD bgcolor="#FBB9AC"><A NAME="ex80"><B>EXERCISE 80:</B><BR>(link to <A HREF="answers2/answer80.html">the answer</A>)<TR><TD><TD>  Write a "megalook'' verb, which looks around and
108
 
examines everything nearby.
109
 
<P>
110
 
 
111
 
Formally, scope determines what you can talk about, which usually
112
 
means what you can see.  But what can you touch?  Suppose a locked
113
 
chest is inside a sealed glass cabinet.  The Inform parser will
114
 
allow the command "unlock chest with key'' and generate the
115
 
appropriate action, <TT>Unlock chest key</TT>, because the chest is in
116
 
scope, so the command at least makes sense.
117
 
<P>
118
 
 
119
 
But it's impossible to carry out, because the player can't reach
120
 
through the solid glass.  So the library's routine for handling the
121
 
<TT>Unlock</TT> action needs to enforce this.  The library does this
122
 
using a stricter rule called "touchability''.  The rule is that
123
 
you can touch anything in scope unless there's a closed container
124
 
between you and it.  This applies either if you're in the container,
125
 
or if it is.
126
 
<P>
127
 
 
128
 
Some purely visual actions don't require touchability -- <TT>Examine</TT>
129
 
or <TT>LookUnder</TT>, for instance.  But most actions are tactile, and
130
 
so will many actions created by designers.  If you want to make
131
 
your own action routines enforce touchability, you can call the
132
 
library routine <TT>ObjectIsUntouchable(obj)</TT>.  This either returns
133
 
<TT>false</TT> if there's no problem in touching <TT>obj</TT>, or returns <TT>true</TT>
134
 
and prints a suitable message (such as "The solid glass cabinet
135
 
is in the way.'').  Thus, the first line of many of the library's
136
 
action routines is:
137
 
<PRE>
138
 
    if (ObjectIsUntouchable(noun)) return;
139
 
</PRE>
140
 
 
141
 
You can also call <TT>ObjectIsUntouchable(obj, true)</TT> to simply return
142
 
true or false, and print nothing, if you'd rather provide your
143
 
own failure message.
144
 
<P>
145
 
 
146
 
 
147
 
The rest of this section is about how to change the scope rules.  As usual
148
 
with Inform, you can change them globally, but it's more efficient and
149
 
safer to work locally.  To take a typical example: how do we allow the
150
 
player to ask questions like the traditional
151
 
"what is a grue''
152
 
?
153
 
The "grue'' part ought to be parsed as if it were a noun, so that
154
 
we could distinguish between, say, a "garden grue'' and a "wild grue''.
155
 
So it isn't good enough to look only at a single word.  Here is one
156
 
solution:
157
 
<PRE>
158
 
Object questions "qs";
159
 
[ QuerySub; print_ret (string) noun.description;
160
 
];
161
 
[ Topic i;
162
 
  switch(scope_stage)
163
 
  {   1: rfalse;
164
 
      2: objectloop (i in questions) PlaceInScope(i); rtrue;
165
 
      3: "At the moment, even the simplest questions confuse you.";
166
 
  }
167
 
];
168
 
</PRE>
169
 
 
170
 
where the actual questions at any time are the current children of
171
 
the <TT>questions</TT> object, like so:
172
 
<PRE>
173
 
Object q1 "long count" questions
174
 
  with name "long" "count",
175
 
       description "The Long Count is the great Mayan cycle of time,
176
 
           which began in 3114 BC and will finish with the world's end
177
 
           in 2012 AD.";
178
 
</PRE>
179
 
 
180
 
and we also have a grammar line:
181
 
<PRE>
182
 
Verb "what"
183
 
                * "is"  scope=Topic              -&#62; Query
184
 
                * "was" scope=Topic              -&#62; Query;
185
 
</PRE>
186
 
 
187
 
Note that the <TT>questions</TT> and <TT>q1</TT> objects are out of the game for every
188
 
other purpose.  The name "qs'' doesn't matter, as it will never appear;
189
 
the individual questions are named so that the parser might be able to say
190
 
"Which do you mean, the long count or the short count?'' if the player
191
 
asked "what is the count''.
192
 
<P>
193
 
 
194
 
When the parser reaches <TABLE Border><TR><TD><TT>scope=Topic</TT></TABLE>, it calls
195
 
the <TT>Topic</TT> routine with the variable <TT>scope_stage</TT> set to 1.  The routine
196
 
should return 1 (true) if it is prepared to allow multiple objects to be
197
 
accepted here, and 0 (false) otherwise: as we don't want "what is
198
 
everything'' to list all the questions and answers in the game, we return
199
 
false.
200
 
<P>
201
 
 
202
 
A little later on in its machinations, the parser again calls <TT>Topic</TT>
203
 
with <TT>scope_stage</TT> now set to 2.  <TT>Topic</TT> is now obliged to
204
 
tell the parser which objects are to be in scope.  It can call two
205
 
parser routines to do this.
206
 
<PRE>
207
 
ScopeWithin(object)
208
 
</PRE>
209
 
 
210
 
puts everything inside the object into scope, though not the object itself;
211
 
<PRE>
212
 
PlaceInScope(object)
213
 
</PRE>
214
 
 
215
 
puts just a single object into scope.  It is perfectly legal to declare
216
 
something in scope that "would have been in scope anyway": or even something
217
 
which is in a different room altogether from the actor concerned, say at the
218
 
other end of a telephone line.  Our scope routine <TT>Topic</TT> should then return
219
 
 
220
 
<P>0 --  (false) to carry on with the usual scope rules, so that everything
221
 
that would usually be in scope still is, or
222
 
<P>1 --  (true) to tell the parser not to put any more objects into scope.
223
 
<P>
224
 
 
225
 
<P>
226
 
So at <TT>scope_stage</TT> 2 it is quite permissible to do nothing but return false,
227
 
whereupon the usual rules apply.  <TT>Topic</TT> returns true because it wants
228
 
only question topics to be in scope, not question topics together with
229
 
the usual miscellany near the player.
230
 
<P>
231
 
 
232
 
This is enough to deal with "what is the long count''.  If on the other
233
 
hand the player typed "what is the lgon cnout'', the error message
234
 
which the parser would usually produce ("You can't see any such thing'')
235
 
would be unsatisfactory.  So if parsing failed at this token, then
236
 
<TT>Topic</TT> is called at <TT>scope_stage</TT> 3 to print out a suitable error
237
 
message.  It must provide one.
238
 
<P>
239
 
 
240
 
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL> Note that <TT>ScopeWithin(object)</TT> extends the scope down through
241
 
its possessions according to the usual rules, i.e., depending on their
242
 
transparency, whether they're containers and so on.  The definition of
243
 
<TT>Topic</TT> above shows how to put just the direct possessions into scope.
244
 
</SMALL>
245
 
<TR><TD><TD><P>
246
 
 
247
 
<P><TR><TD Valign="top"><IMG SRC="icons/exercise.gif" ALT="??"><TD bgcolor="#FBB9AC"><A NAME="ex81"><B>EXERCISE 81:</B><BR>(link to <A HREF="answers2/answer81.html">the answer</A>)<TR><TD><TD> Write a token which puts everything in scope, so that you could
248
 
have a debugging "purloin'' verb which could take anything, regardless
249
 
of where it was and the rules applying to
250
 
it.
251
 
<P>
252
 
 
253
 
<P>
254
 
Changing the global definition of scope should be done cautiously
255
 
(there may be unanticipated side effects); bear in mind that scope decisions
256
 
need to be taken often -- every time an object token is parsed, so perhaps
257
 
five to ten times in every game turn -- and hence moderately
258
 
quickly.
259
 
The global definition can be tampered with by providing the entry point
260
 
<PRE>
261
 
InScope(actor)
262
 
</PRE>
263
 
 
264
 
where the <TT>actor</TT> is usually the player, but not always.  If the routine
265
 
decides that a particular object should be in scope for the actor,
266
 
it should execute <TT>PlaceInScope</TT> and <TT>ScopeWithin</TT> just as above, and return
267
 
true or false, as if it were at <TT>scope_stage</TT> 2.  Thus, it is vital to
268
 
return false in circumstances when you don't want to intervene.
269
 
<P>
270
 
 
271
 
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL> The token <TABLE Border><TR><TD><TT>scope=</TT><I><B>&#60;Routine&#62;</B></I></TABLE> takes precedence over
272
 
<TT>InScope</TT>, which will only be reached if the routine returns
273
 
false to signify 'carry on'.
274
 
</SMALL>
275
 
<TR><TD><TD><P>
276
 
 
277
 
<P><TR><TD Valign="top"><IMG SRC="icons/ddbend.gif" ALT="/\/\"><TD bgcolor="#EEEEEE"><SMALL> There are seven reasons why <TT>InScope</TT> might be being
278
 
called; the <TT>scope_reason</TT> variable is set to the current
279
 
one:
280
 
<TR><TD><TD bgcolor="#EEEEEE"><SMALL>
281
 
 
282
 
<DL>
283
 
<DT><B><TT>PARSING_REASON</TT></B><DD>
284
 
 
285
 
The usual one.  Note that <TT>action_to_be</TT> holds
286
 
<TT>NULL</TT> in the early stages (before the verb has been decided)
287
 
and later on the action which would result from a successful match.
288
 
<DT><B><TT>TALKING_REASON</TT></B><DD>
289
 
 
290
 
Working out which objects are in scope for being spoken to (see
291
 
the end of <A HREF="section16.html">Section 16</A> for exercises using this).
292
 
<DT><B><TT>EACHTURN_REASON</TT></B><DD>
293
 
 
294
 
When running <TT>each_turn</TT> routines for anything nearby, at the end of
295
 
each turn.
296
 
<DT><B><TT>REACT_BEFORE_REASON</TT></B><DD>
297
 
 
298
 
When running <TT>react_before</TT>.
299
 
<DT><B><TT>REACT_AFTER_REASON</TT></B><DD>
300
 
 
301
 
When running <TT>react_after</TT>.
302
 
<DT><B><TT>TESTSCOPE_REASON</TT></B><DD>
303
 
 
304
 
When performing a <TT>TestScope</TT>.
305
 
<DT><B><TT>LOOPOVERSCOPE_REASON</TT></B><DD>
306
 
 
307
 
When performing a <TT>LoopOverScope</TT>.
308
 
</DL>
309
 
 
310
 
</SMALL>
311
 
<TR><TD><TD><P>
312
 
 
313
 
<P>
314
 
Here are some examples.  Firstly, as promised, how to change the
315
 
rule that "things you've just dropped disappear in the dark":
316
 
<PRE>
317
 
[ InScope person i;
318
 
  if (person==player &#38;&#38; location==thedark)
319
 
      objectloop (i near player)
320
 
          if (i has moved)
321
 
              PlaceInScope(i);
322
 
  rfalse;
323
 
];
324
 
</PRE>
325
 
 
326
 
With this routine added, the objects in the dark room the player
327
 
is in are in scope only if they have <TT>moved</TT> (that is, have been held by
328
 
the player in the past); and even then, are in scope only to the player.
329
 
<P>
330
 
 
331
 
<P><TR><TD Valign="top"><IMG SRC="icons/ddexercise.gif" ALT="??/\/\"><TD bgcolor="#FBB9AC"><A NAME="ex82"><B>EXERCISE 82:</B><BR>(link to <A HREF="answers2/answer82.html">the answer</A>)<TR><TD><TD> Construct a long room divided by a glass window.
332
 
Room descriptions on either side should describe what's in view on
333
 
the other; the window should be lookable-through; objects on the far
334
 
side should be in scope, but not manipulable; and everything should
335
 
cope well if one side is in
336
 
darkness.
337
 
 
338
 
<P>
339
 
 
340
 
<P><TR><TD Valign="top"><IMG SRC="icons/ddexercise.gif" ALT="??/\/\"><TD bgcolor="#FBB9AC"><A NAME="ex83"><B>EXERCISE 83:</B><BR>(link to <A HREF="answers2/answer83.html">the answer</A>)<TR><TD><TD> Code the following puzzle.
341
 
In an initially dark room there is a light switch.
342
 
Provided you've seen the switch at some time in the past, you can turn
343
 
it on and off -- but before you've ever seen it, you can't.  Inside the
344
 
room is nothing you can see, but you can hear a dwarf breathing.  If you
345
 
tell the dwarf to turn the light on, he
346
 
will.
347
 
 
348
 
<P>
349
 
 
350
 
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL> Alternatively, it may contain a routine.  This routine can then
351
 
call <TT>AddToScope(x)</TT> to put any object <TT>x</TT> into scope.  It may not,
352
 
however, call <TT>ScopeWithin</TT> or any other scoping routines.
353
 
</SMALL>
354
 
<TR><TD><TD><P>
355
 
 
356
 
<P><TR><TD Valign="top"><IMG SRC="icons/ddbend.gif" ALT="/\/\"><TD bgcolor="#EEEEEE"><SMALL> Scope addition does <I> not</I> occur for an object moved
357
 
into scope by an explicit call to <TT>PlaceInScope</TT>, since this must allow
358
 
complete freedom in scope selections.  But it does happen when objects
359
 
are moved in scope by calls to <TT>ScopeWithin(domain)</TT>.
360
 
</SMALL>
361
 
<TR><TD><TD><P>
362
 
 
363
 
<P><TR><TD Valign="top"><IMG SRC="icons/exercise.gif" ALT="??"><TD bgcolor="#FBB9AC"><A NAME="ex84"><B>EXERCISE 84:</B><BR>(link to <A HREF="answers2/answer84.html">the answer</A>)<TR><TD><TD> (From the tiny example game 'A Nasal Twinge'.)  Give the
364
 
player a nose, which is always in scope and can be held, reducing
365
 
the player's carrying capacity.
366
 
<P>
367
 
 
368
 
<P><TR><TD Valign="top"><IMG SRC="icons/exercise.gif" ALT="??"><TD bgcolor="#FBB9AC"><A NAME="ex85"><B>EXERCISE 85:</B><BR>(link to <A HREF="answers2/answer85.html">the answer</A>)<TR><TD><TD> (Likewise.)  Create a portable sterilising machine, with a
369
 
"go'' button, a top which things can be put on and an inside to hold
370
 
objects for sterilisation.  (Thus it is a container, a supporter
371
 
and a possessor of sub-objects all at
372
 
once.)
373
 
<P>
374
 
 
375
 
<P><TR><TD Valign="top"><IMG SRC="icons/ddexercise.gif" ALT="??/\/\"><TD bgcolor="#FBB9AC"><A NAME="ex86"><B>EXERCISE 86:</B><BR>(link to <A HREF="answers2/answer86.html">the answer</A>)<TR><TD><TD> Create a red sticky label which the player can affix
376
 
to any object in the game.  (Hint: use <TT>InScope</TT>, not
377
 
<TT>add_to_scope</TT>.)
378
 
<P>
379
 
 
380
 
<P><TR><TD Valign="top"><IMG SRC="icons/refs.gif" ALT="*"><TD bgcolor="#EEEEEE"><B>REFERENCES:</B><BR><SMALL>  'Balances' uses <TABLE Border><TR><TD><TT>scope = </TT><I><B>&#60;routine&#62;</B></I></TABLE> tokens
381
 
for legible spells and memorised spells.
382
 
<BR>  See also the exercises at the end of <A HREF="section16.html">Section 16</A> for further
383
 
scope trickery.
384
 
</SMALL>
385
 
<TR><TD><TD><P>
386
 
 
387
 
 
388
 
</TABLE>
389
 
<HR><A HREF="contents.html">Contents</A> / <A HREF="section27.html">Back</A> / <A HREF="section29.html">Forward</A> <BR>
390
 
<A HREF="chapter1.html">Chapter I</A> / <A HREF="chapter2.html">Chapter II</A> / <A HREF="chapter3.html">Chapter III</A> / <A HREF="chapter4.html">Chapter IV</A> / <A HREF="chapter5.html">Chapter V</A> / <A HREF="chapter6.html">Chapter VI</A> / <A HREF="chapterA.html">Appendix</A><HR><SMALL><I>Mechanically translated to HTML from third edition as revised 16 May 1997. Copyright &#169; Graham Nelson 1993, 1994, 1995, 1996, 1997: all rights reserved.</I></SMALL></BODY></HTML>