1
<HTML><HEAD><TITLE>Section 28: Scope and what you can see</TITLE></HEAD>
2
<BODY BGCOLOR="#FFFFFF">
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>
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>
12
<BR>Wherefore are these things hid?
13
<BR><P>...William Shakespeare (<B>1564</B>--<B>1616</B>), <I>Twelfth Night</I></BLOCKQUOTE>
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
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'
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>
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.)
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:
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>
48
In addition, if an object is in scope then anything which
49
it "adds to scope'' is also in scope.
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;
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.
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.
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.
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.
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
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
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.
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.
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,
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
138
if (ObjectIsUntouchable(noun)) return;
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
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
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
158
Object questions "qs";
159
[ QuerySub; print_ret (string) noun.description;
164
2: objectloop (i in questions) PlaceInScope(i); rtrue;
165
3: "At the moment, even the simplest questions confuse you.";
170
where the actual questions at any time are the current children of
171
the <TT>questions</TT> object, like so:
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
180
and we also have a grammar line:
183
* "is" scope=Topic -> Query
184
* "was" scope=Topic -> Query;
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''.
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
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.
210
puts everything inside the object into scope, though not the object itself;
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
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.
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.
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.
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.
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
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
259
The global definition can be tampered with by providing the entry point
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.
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><Routine></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'.
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
280
<TR><TD><TD bgcolor="#EEEEEE"><SMALL>
283
<DT><B><TT>PARSING_REASON</TT></B><DD>
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>
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>
294
When running <TT>each_turn</TT> routines for anything nearby, at the end of
296
<DT><B><TT>REACT_BEFORE_REASON</TT></B><DD>
298
When running <TT>react_before</TT>.
299
<DT><B><TT>REACT_AFTER_REASON</TT></B><DD>
301
When running <TT>react_after</TT>.
302
<DT><B><TT>TESTSCOPE_REASON</TT></B><DD>
304
When performing a <TT>TestScope</TT>.
305
<DT><B><TT>LOOPOVERSCOPE_REASON</TT></B><DD>
307
When performing a <TT>LoopOverScope</TT>.
314
Here are some examples. Firstly, as promised, how to change the
315
rule that "things you've just dropped disappear in the dark":
318
if (person==player && location==thedark)
319
objectloop (i near player)
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.
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
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
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.
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>.
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.
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
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>.)
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><routine></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
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 © Graham Nelson 1993, 1994, 1995, 1996, 1997: all rights reserved.</I></SMALL></BODY></HTML>