cfad47cfa3/t3compiler/tads3/lib/adv3/changes.htm

4b825dc642cb6eb9a060e54bf8d69288fbee4904cfad47cfa334b206c65f22086bcc5d63e6f70944
1
<html>
2
<title>Recent Changes to the TADS 3 Library</title>
3
4
<style type="text/css"><!--
5
6
div.sepbar {
7
   width: 100%;
8
   padding-left: 5px;
9
   padding-right: 5px;
10
   padding-top: 3px;
11
   padding-bottom: 3px;
12
   margin-bottom: 1.5em;
13
   margin-top: 1.5em;
14
   background: #c0c0f0;
15
   color: #000040;
16
   font-size: 125%;
17
   text-align: center;
18
}
19
20
div.firstentry {
21
   padding: 0em .5ex 1em .5ex;
22
   margin: 0px .5ex 0px .5ex;
23
   border-top: none;
24
}
25
26
div.entry {
27
   padding: 1em .5ex 1em .5ex;
28
   margin: 0px .5ex 0px .5ex;
29
   border-top: 1px solid #c0c0c0;
30
}
31
32
--></style>
33
34
<body>
35
36
<h1>Recent Changes to the TADS 3 Library</h1>
37
38
<p>This is a list of changes to adv3, the TADS 3 library.
39
Changes are listed in reverse chronological order (the most recent
40
changes are first).
41
42
<ul>
43
<li><a href='#3018a'>3.0.18.1</a>
44
<li><a href='#3018'>3.0.18</a>
45
<li><a href='#3017a'>3.0.17.1</a>
46
<li><a href='#3017'>3.0.17</a>
47
<li><a href='#3016'>3.0.16</a>
48
<li><a href='#3015c'>3.0.15.3</a>
49
<li><a href='#3015b'>3.0.15.2</a>
50
<li><a href='#3015a'>3.0.15.1</a>
51
<li><a href='#3015'>3.0.15</a>
52
<li><a href='#3014'>3.0.14</a>
53
<li><a href='#3013'>3.0.13</a>
54
<li><a href='#3012'>3.0.12</a>
55
<li><a href='#3011'>3.0.11</a>
56
<li><a href='#3010'>3.0.10</a>
57
<li><a href='#309'>3.0.9</a>
58
<li><a href='#308'>3.0.8</a>
59
<li><a href='#307'>3.0.7</a>
60
<li><a href='#306q'>3.0.6q</a>
61
<li><a href='#306p'>3.0.6p</a>
62
<li><a href='#306o'>3.0.6o</a>
63
<li><a href='#306n'>3.0.6n</a>
64
<li><a href='#306m'>3.0.6m</a>
65
<li><a href='#306l'>3.0.6l</a>
66
<li><a href='#306k'>3.0.6k</a>
67
<li><a href='#306j'>3.0.6j</a>
68
<li><a href='#306i'>3.0.6i</a>
69
<li><a href='#306h'>3.0.6h</a>
70
<li><a href='#306g'>3.0.6g</a>
71
<li><a href='#306f'>3.0.6f</a>
72
<li><a href='#306ae'>3.0.6a-e</a>
73
<li><a href='#305'>3.0.5</a>
74
<li><a href='#304'>3.0.4 and earlier</a>
75
</ul>
76
77
<!------------------------------- 3.0.18.1 --------------------------------->
78
<div class="sepbar"><a name='3018a'></a>3.0.18.1</div>
79
<p><b><i>Released 5/5/2009</i></b>
80
<p>
81
82
<!------------------->
83
<div class=firstentry>
84
85
A typo in the English message for refuseCommand has been fixed.
86
   
87
</div>
88
89
90
<!------------------------------- 3.0.18 --------------------------------->
91
<div class="sepbar"><a name='3018'></a>3.0.18</div>
92
<p><b><i>Released 4/28/2009</i></b>
93
<p>
94
95
<!------------------->
96
<div class=firstentry>
97
98
More of the lister classes have been reorganized along the same lines
99
as the BaseContentsLister refactoring in version 3.0.17.  In particular:
100
101
<ul>
102
   <li>surfaceLookInLister, undersideLookUnderLister, and rearLookBehindLister
103
   are now trivial classes based on the new class LookWhereContentsLister.
104
   For consistency, thingLookInLister is based on the new class as well,
105
   but is non-trivial due to its different wording.
106
107
   <li>surfaceInlineContentsLister, undersideInlineContentsLister, and
108
   rearInlineContentsLister are now trivial classes based on the new class
109
   BaseInlineContentsLister.  For consistency, inlineContentsLister
110
   is also based on the new base class, but is non-trivial due to
111
   its different wording.
112
   
113
</ul>
114
   
115
</div>
116
117
<!------------------->
118
<div class=entry>
119
120
When an action remapping is inherited from a base class, a subclass or
121
instance can now define a verify() method for the original action.  In
122
the past, only the <b>new</b> action's verify() was called - the
123
remapping bypassed any dobjFor() or iobjFor() definitions for the
124
old action.  This made it impossible to tweak the subclass handling
125
for verbs that were remapped in base classes.
126
127
<p>With this change, the verify() for the <b>new and old</b> actions
128
are <b>both</b> called, <b>if</b> there's a verify() for the old
129
action defined on a subclass of the class where the remap() itself is
130
defined.  In other words, if the verify() "overrides" the remap(), the
131
subclassed verify() is invoked.
132
133
<p>Because the verify() methods for both the old and new actions are
134
called, you can't actually override the new action's verify() call.
135
But verify() results are cumulative, so you <i>can</i> use it to
136
adjust the logicalness of the action, or to make the action illogical.
137
138
</div>
139
140
<!------------------->
141
<div class=entry>
142
143
The parser can now has an option to generate more descriptive messages
144
when noun phrases are disambiguated using the logicalness rules.
145
146
<p>Disambiguation occurs when the player uses a noun phrase that
147
matches more than one in-scope object.  For example, if the current
148
room contains a red door and a blue door, and the player types OPEN
149
DOOR, the noun phrase DOOR could refer to either of the two door
150
objects.  The parser must decide which of the two objects the player
151
is referring to; this process is called disambiguation.  The parser
152
does this by applying the various logical, logicalRank, illogicalNow,
153
illogicalAlready, and related rules defined on the matching objects in
154
the library and in your game code.
155
156
<p>There are two kinds of disambiguation results: "clear" and
157
"unclear".  When exactly one of the objects involved is logical, it's
158
a clear disambiguation result: we consider it safe to assume that the
159
player was referring to that exact object, since the other choices
160
simply don't make sense.  When more than one object is logical,
161
though, the parser can sometimes still pick one automatically (i.e.,
162
without generating an extra question asking the player to specify
163
which one she intended) based on the "likelihood" rankings given by
164
logicalRank rules.  A pick based on likelihood rankings is an unclear
165
result, because the player could plausibly have been referring to one
166
of the other logical matches.
167
168
<p>For unclear results, the parser has always generated a
169
parenthetical announcement saying which object it chose.  This is to
170
alert the player to the parser's choice, so that any misunderstanding
171
is immediately apparent.
172
173
<p>However, in past versions, the parser didn't say anything to
174
explicate clear disambiguation results.  In practice, even clear
175
results can sometimes disagree with the player's intentions, for the
176
simple reason that the player sometimes misunderstands the current
177
state of the objects.  So some authors have found that it's better to
178
make some kind of object announcement in every case, regardless of how
179
clear the parser thinks the resolution is.
180
181
<p>The parser now provides two new modes, in addition to the
182
traditional mode, for announcing clear disambiguation results.  These
183
new modes are selected via the new gameMain property ambigAnnounceMode.
184
You can set this in your gameMain object to select the behavior you
185
prefer.  The settings are:
186
187
<ul>
188
189
   <li>AnnounceUnclear: The parser makes a parenthetical announcement
190
   (such as "(the red door)") only when a disambiguation result is
191
   unclear.  It doesn't make any announcements for clear disambiguation
192
   results, or when only one in-scope object matches a noun phrase.
193
   This is the traditional behavior that the library used before the
194
   new options were added.
195
196
   <li>AnnounceClear: The parser makes a parenthetical announcement
197
   for <i>any</i> disambiguation result, whether clear or unclear.
198
   No announcement is generated when there's no disambiguation, though
199
   (that is, the noun phrase itself matches only one in-scope object).
200
201
   <li>DescribeClear: For unclear disambiguation, the parser makes the
202
   traditional parenthetical announcement.  For clear disambiguation,
203
   the parser skips the parenthetical announcement, but it uses more
204
   detailed default reply messages in lieu of the ultra-terse defaults,
205
   such as "Taken" or "Dropped".  For example, instead of just "Taken",
206
   the parser replies "You take the dusty old tome."  The longer messages
207
   mention the objects involved by name, so they provide the same
208
   information as the parenthetical announcements, but in a somewhat
209
   less conspicuous and mechanistic way.
210
211
</ul>
212
213
<p>Note that the new default behavior differs from the old behavior
214
from before this feature was added.  If you prefer the old behavior,
215
you must explicitly set gameMain.ambigAnnounceMode to AnnounceUnclear.
216
217
<p>The short-vs-long message selection for the DescribeClear option is
218
done through a couple of new MessageHelper methods, shortTMsg() and
219
shortTIMsg().  If you're adding new messages of your own, you can use
220
these methods to do the same type of selection.
221
222
</div>
223
224
<!------------------->
225
<div class=entry>
226
227
The parser can now accept short-hand replies to disambiguation queries
228
involving a locational qualifier, using nothing more than an adjective
229
or noun from one of the location names.  For example:
230
231
<p><pre>
232
&lt;take torch
233
Which torch do you mean, the torch in the left sconce, or the torch in
234
the right sconce?
235
236
&gt;left
237
Taken.
238
</pre>
239
240
<p>In the past, it was necessary for the response to be explicit about
241
the location qualification: THE TORCH IN THE LEFT SCONCE, THE ONE IN
242
THE LEFT, etc.  In particular, the response had to actually use the
243
locational phrasing to refer to the distinguishing location.  This is
244
no longer necessary; a player can now simply name one of the
245
locations, and can even abbreviate to a single distinguishing word
246
from the location name.
247
248
<p>To support this change, the DisambigResolver now keeps track of the
249
Distinguisher that was used to generate the question (the prompting
250
message - "Which torch do you mean...?").  This lets the resolver look
251
for qualifying phrases relevant to the distinguishing characteristic
252
called out in the prompt.
253
254
<p>The Distinguisher, meanwhile, has a couple of new methods that let
255
it provide the added information: objInScope() lets the distinguisher
256
add qualifying objects to the scope list, and matchName() lets the
257
distinguisher recognize qualifying objects in addition to the original
258
ambiguous objects.  The locational and ownership distinguishers
259
defined in the library provide suitable definitions for these new
260
methods.  Games that define their own custom Distinguisher subclasses
261
might want to add these methods if they also make use of ancillary
262
qualifier objects.
263
264
</div>
265
266
<!------------------->
267
<div class=entry>
268
269
In the English library, PathPassage adjusts the logicalness of
270
the verbs Enter and Go Through downward (to logical rank 50).  These
271
verbs aren't usually used with path-like objects in English;
272
this logicalness adjustment tells the parser to pick other objects
273
first in cases of ambiguity.
274
275
</div>
276
277
<!------------------->
278
<div class=entry>
279
280
The new conversationManager method setRevealed(key) adds the given key
281
to the revealed topic table.  The library now calls this method any
282
time it needs to add a key to the table (whereas it used to manipulate
283
the table directly).
284
285
<p>These changes don't affect any existing behavior - existing code
286
will continue to work unchanged.  The purpose of the changes is to
287
provide a single point for overriding the default library behavior via
288
'modify'.  In particular, you can override setRevealed() to store
289
additional information about the revealed topic in its table entry,
290
beyond the mere fact of the revelation.  You could, for example, store
291
the location where the key was revealed, or a time stamp marking when
292
it was revealed.
293
294
</div>
295
296
<!------------------->
297
<div class=entry>
298
299
A new ConvNode method, noteActiveReason(reason), extends the older
300
noteActive() method by providing information on why the node is being
301
activated.  The 'reason' parameter is a string indicating what
302
triggered the node change:
303
304
<ul>
305
   <li>'convnode' - processing a &lt;.convnode&gt; tag
306
   <li>'convend' - processing a &lt;.convend&gt; tag
307
   <li>'initiateConversation' - a call to Actor.initiateConversation()
308
   <li>'endConversation' - a call to Actor.endConversation()
309
</ul>
310
311
<p>By default, this new method simply ignores the reason code and
312
calls the noteActive() method.  This ensures that existing code will
313
work unchanged.
314
315
<p>If you need the reason information when activating the node,
316
override noteActiveReason().  Otherwise, you can override noteActive()
317
as in the past.
318
319
<p>The new reason code information is supplied when the caller changes
320
the node by calling the new Actor method setConvNodeReason().  This is
321
essentially an extended version of the existing setConvNode() method.
322
The new method takes an additional argument giving the reason code,
323
which it passes to noteActiveReason().
324
325
<p>Note that the reason code will be nil if the node change is
326
initiated by calling Actor.setConvNode() directly.  All of the library
327
calls to setConvNode() have been replaced by calls to
328
setConvNodeReason(), so unless your game code is calling setConvNode()
329
directly, the reason code will always be set properly.  For
330
compatibility with existing code, setConvNode() can still be called;
331
it works as before, simply passing a nil reason code.
332
333
</div>
334
335
<!------------------->
336
<div class=entry>
337
338
<a name="3018-byetopic-convnode"></a>In the past, when an actor used
339
conversational states (ConversationReadyState, InConversationState),
340
terminating the conversation didn't take into account any ByeTopic
341
objects in the current ConvNode within the conversation.  This was
342
because the conversation states have some special transition handling
343
that overrides the usual code where the ConvNode ByeTopic would be
344
found.  The conversation states now take care to check the ConvNode
345
in effect at the end of the conversation, so ByeTopic objects within
346
a ConvNode should now interact properly with conversation states.
347
348
</div>
349
350
<!------------------->
351
<div class=entry>
352
353
The transformation from "X, GIVE ME Y" to "ASK X FOR Y" that was
354
introduced in 3.0.17 caused a run-time error if "Y" was a valid word
355
but didn't resolve to an object.  This has been corrected.
356
(<a href="http://bugdb.tads.org/view.php?id=0000021">bugdb.tads.org #0000021</a>)
357
358
359
</div>
360
361
<!------------------->
362
<div class=entry>
363
364
In the past, when EXAMINE was used with ItemizingCollectiveGroup, the
365
output omitted any object that wasn't listable through the room
366
contents lister.  This was a problem for objects such as Fixtures,
367
which normally aren't displayed in a room listing.
368
369
<p>ItemizingCollectiveGroup now calls a new method on self,
370
examineUnlisted(x), to list each object <i>x</i> that isn't listed
371
via the room contents lister.  By default, this new method performs
372
a nested EXAMINE command on the unlisted object to show its full
373
description.
374
375
</div>
376
377
<!------------------->
378
<div class=entry>
379
380
In Settable, the message routing properties have been changed
381
slightly.  In the past, the message properties okaySetToMsg and
382
setToInvalidMsg were doubly redirected: okaySetToMsg had the value
383
&amp;okaySetToMsg, and setToInvalidMsg had the value
384
&amp;setToInvalidMsg.  The TurnTo action handler that used these
385
messages evaluated the properties directly, to get the property
386
pointers, which the library then processed in the usual way.
387
388
<p>The point of this arrangement was that subclasses of Settable (Dial
389
in particular) could easily redirect these messages to different
390
library messages, just by overriding the properties.  However, this
391
was inconsistent with the message scheme most other objects use, in
392
that you couldn't override okaySetToMsg(val) in the Settable itself to
393
yield the message text, which is how the message scheme works for
394
most other objects.
395
396
<p>The new version keeps the redirection step, but renames it to allow
397
the standard override scheme to be used.  The new property okaySetToMsgProp
398
evaluates to &amp;okaySetToMsg, and setToInvalidMsgProp evaluates to
399
&amp;setToInvalidMsg.  This means that you can override okaySetToMsg(val)
400
and setToInvalidMsg(val) using the standard pattern.
401
402
<p>(<a href="http://bugdb.tads.org/view.php?id=0000045">bugdb.tads.org #0000045</a>)
403
404
</div>
405
406
<!------------------->
407
<div class=entry>
408
409
Underside and RearContainer now provide tryMovingObjInto() method
410
definitions.  The new methods try the obvious implied commands
411
suitable for these objects: Underside tries an implied PutUnder, and
412
RearContainer tries an implicit PutBehind.
413
414
</div>
415
416
<!------------------->
417
<div class=entry>
418
419
The BannerWindow method updateForRestore() is now called during a
420
Restore or Undo operation for every banner, even when the banner is
421
already displayed.  In the past, this method wasn't called on banner
422
windows that were already present; it was only called when the window
423
had to be created in the course of the Restore/Undo.  It's now called
424
uniformly for all banners.
425
426
</div>
427
428
<!------------------------------- 3.0.17.1 --------------------------------->
429
<div class="sepbar"><a name='3017a'></a>3.0.17.1</div>
430
<p><b><i>Released 8/12/2008</i></b>
431
<p>
432
433
<!------------------->
434
<div class=firstentry>
435
436
<i>This version has no library changes; this release is to correct
437
a TADS 3 compiler problem introduced in 3.0.17.</i>
438
   
439
</div>
440
441
442
<!------------------------------- 3.0.17 --------------------------------->
443
<div class="sepbar"><a name='3017'></a>3.0.17</div>
444
<p><b><i>Released 8/9/2008</i></b>
445
<p>
446
447
<!------------------->
448
<div class=firstentry>
449
450
<b>Risk of incompatibility:</b> The standard handling for the TakeFrom
451
action has been changed slightly.  The changes generally make it
452
easier to code objects by unifying the handling of Take and TakeFrom
453
for most objects, but some slight adjustments to existing code might
454
be required - see below.
455
456
<p>First, Thing.dobjFor(TakeFrom)'s action() handler now actually
457
replaces the TakeFrom with a Take action.  In the past, the handler
458
merely invoked the Take action() handler.  For the most part, this had
459
the same effect as replacing the action, but not always; some
460
arrangements of subclasses and overrides caused subtle differences.
461
Actually replacing the action ensures that a successful TakeFrom is
462
handled <i>exactly</i> like a regular Take, which means that custom
463
behavior for Take will automatically apply exactly the same way to
464
TakeFrom without any explicit TakeFrom overrides.  Of course, you can
465
still override dobjFor(TakeFrom) separately if you do want it to
466
behave differently from Take.
467
468
<p>Second, Immovable.dobjFor(Take) now fails the action in the check()
469
handler rather than the action handler, which allows us to remove
470
Immovable.dobjFor(TakeFrom) entirely.  In the past, TakeFrom was
471
separately overridden to ensure that the indirect object wouldn't
472
attempt to carry out the action, but this is no longer necessary,
473
since the basic Take check() phase (which TakeFrom's check() phase
474
invokes) will fail the command.
475
476
<p>These two changes should essentially eliminate the need to override
477
TakeFrom when all you want to do is make it behave the same as Take.
478
TakeFrom should now always follow Take's lead, so if you simply want
479
TakeFrom and Take to behave the same way, just override Take and
480
you're set.
481
482
<p>Some existing code might not work properly with the changes to
483
Immovable.  In particular, you'll need to look at any objects of class
484
Immovable (or any subclass of Immovable) where you've overridden the
485
dobjFor(Take) action() handler.  In the past, overriding the action()
486
handler for Take was enough to override Immovable's handling of the
487
command, since Immovable failed the command in the action() handler
488
and did nothing in the check() handler.  With the change, the check()
489
handler cancels the action.  This means that your overridden action()
490
handler might never be invoked.  The solution is simply to insert an
491
empty dobjFor(Take) check() handler in your object:
492
493
<p>
494
<pre>
495
   boulder: Immovable 'boulder' 'boulder' "It's a big boulder. "
496
      dobjFor(Take)
497
      {
498
        verify()
499
           { /* my original verify routine... */ }
500
        check() { }   // THIS HAD TO BE ADDED DUE TO THE LIBRARY CHANGE !!!
501
        action()
502
           { /* my original action routine... */ }
503
      }
504
    ;
505
</pre>
506
507
<p>If you're not sure whether you have any objects needing this change,
508
you can add this bit of code to your game, and then run the game and
509
type IMMTEST to get a list of objects that you should inspect:
510
511
<p>
512
<pre>
513
   VerbRule(immtest) 'immtest' : IAction
514
     execAction()
515
     {
516
       "Immovables with dobjFor(Take) action() overrides:\n";
517
       forEachInstance(Immovable, new function(x)
518
       {
519
         if (overrides(x, Immovable, &actionDobjTake))
520
           "\t!!! <<x.name>>\n";
521
       });
522
     }
523
   ;
524
</div>
525
526
<!------------------->
527
<div class=entry>
528
529
Krister Fundin's Tips extension has now been integrated into the
530
library as a standard feature.  This system makes it easy to create
531
custom one-time tips of the sort that the library has traditionally
532
used for things like the explanation of the NOTIFY command the first
533
time the game's score changes.  The library now uses the Tips system
534
for its standard tips, and the system is readily extensible with
535
custom, game-specific tips.  A new chapter in the <i>Technical
536
Manual</i> describes the system.
537
538
</div>
539
540
<!------------------->
541
<div class=entry>
542
543
544
It's now possible to determine if a script file is currently being
545
read, and if so, the modes being used to read it.  To get this
546
information, call <tt>setScriptFile(ScriptReqGetStatus)</tt>.  If
547
input is currently being read from a script, the function returns an
548
integer value giving a combination of <tt>ScriptFileXxx</tt> flags
549
describing the reading mode; for example, the return value will be
550
<tt>(ScriptFileQuiet | ScriptFileNonstop)</tt> for a script being read
551
in quiet, non-stop mode.  Note that a return value of 0 (zero)
552
indicates that a script <b>is</b> being read, but that none of the
553
mode flags are applicable - that is, the script is being read in the
554
default modes, with output and "more" prompts displayed.  If a script
555
is <b>not</b> currently being read, the return value is nil.
556
557
<p>The new flag <tt>ScriptFileEvent</tt> will be included in the
558
return value if applicable.  This lets you determine whether the
559
script being read is an event script or a plain command-line script.
560
Note that this new flag is "query only" - if you include it in the
561
'flags' argument in a call to setScriptFile() to start reading a
562
script, the function ignores it, since the script reader determines
563
the type of the script to be read automatically by examining the
564
file's contents.  The purpose of this flag is to let you find out how
565
the script reader is treating the file, rather than letting you tell
566
the script reader how to treat the file.
567
568
<p>Note that this new form of setScriptFile() is only supported in VM
569
versions 3.0.17 and higher.  If you call
570
<tt>setScriptFile(ScriptReqGetStatus)</tt> on an earlier VM, a
571
run-time error result, because older implementations of the function
572
accept only a filename string or nil as the first argument.  You can
573
use try-catch to handle this situation - a run-time error indicates
574
that this form of the function isn't supported, in which case the
575
script status information is not available.
576
577
</div>
578
579
<!------------------->
580
<div class=entry>
581
582
Two new actions have been added: RecordEvents and RecordEventsString.
583
These are variations on the Record and RecordString actions that
584
record event scripts (rather than ordinary command scripts, as Record
585
and RecordString do).  The English library defines verb syntax for
586
these new actions ("record events", "record events on", and "record
587
events '<i>filename</i>'").
588
589
</div>
590
591
<!------------------->
592
<div class=entry>
593
594
A new parsing mechanism makes it possible to rewrite commands based on
595
"global" conditions.  Unlike remapTo, which lets you associate
596
remapping rules with the objects involved in the command, the new
597
mechanism lets you rewrite a command even before the objects are
598
resolved.  There are cases where it's important to be able to apply
599
the rewrite before any object resolution has taken place, because the
600
resolution process itself can vary substantially depending on the type
601
of action being performed.  remapTo has to wait until after objects
602
are resolved, which is sometimes too late.
603
604
<p>This new mechanism is implemented via a new class, GlobalRemapping.
605
To create a rewrite rule, you create a GlobalRemapping object, and
606
define its getRemapping() method.  This method looks at the action to
607
determine if it's of interest, using whatever criteria you want.  In
608
most cases, this means checking the action type to see if it's an
609
action you want to rewrite, and possibly checking to see if certain
610
objects are involved as well.
611
612
<p>The library defines one GlobalRemapping object, giveMeToAskFor,
613
which rewrites commands of the form "X, GIVE ME Y" to the alternative
614
format "ME, ASK X FOR Y".  The library formerly <i>tried</i> to
615
perform this same rewriting via an iobjFor(GiveTo) check() method in
616
Actor, but this approach didn't work in many cases due to interference
617
from several other checks made earlier in the execution process.  The
618
old check() scheme has been deleted in favor of the new mechanism.
619
620
<p>For full details, see the new chapter on Global Command Remapping
621
in the <i>Technical Manual</i>.
622
623
</div>
624
625
<!------------------->
626
<div class=entry>
627
628
A new set of Action methods makes it possible to temporarily override
629
the meaning of a pronoun, for as long as the action is in effect.
630
Action.setPronounOverride() creates an override, which associates an
631
object with a particular pronoun type (PronounMe, PronounYou, etc).
632
This new meaning overrides the usual meaning, but only for the
633
duration of the action.  Action.getPronounOverride() looks for an
634
override defined with setPronounOverride() for this action.
635
636
<p>This new mechanism is designed mainly to support GlobalRemapping.
637
In particular, a remapping that changes the target actor usually needs
638
to override the meaning of "you" in the rewritten action, so that
639
"you", "your", and "yours" are interpreted as referring to the
640
<i>original</i> target actor rather than the target actor of the
641
rewritten format.
642
643
<p>For details, see the new chapter "Global Command Remapping" in
644
the <i>Technical Manual</i>.
645
646
</div>
647
648
<!------------------->
649
<div class=entry>
650
651
The classes BaseSurfaceContentsLister, BaseRearContentsLister, and
652
BaseUndersideContentsLister are now all based on a new class,
653
BaseContentsLister.  This new class unifies the code that was formerly
654
defined separately in the three subclasses -
655
BaseSurfaceContentsLister, BaseRearContentsLister, and
656
BaseUndersideContentsLister are now trivial subclasses with no
657
overrides of their own.  (They're still present as separate classes,
658
(1) for the sake of compatibility with existing code, and (2) because
659
the distinct classes could still be useful for other types of
660
container-type-specific overrides beyond what the library defines.)
661
662
<p>The three subclasses exist to provide customized wording in the
663
contents listings generated for the corresponding specialized
664
container types.  However, the variation in the wording provided by
665
the library definitions was always very simple - the only thing that
666
varies is the preposition used to describe the relationship between
667
the container and its contents ("on" for a Surface, "under" for an
668
Underside object, "behind" for a RearContainer or RearSurface).  As it
669
turns out, the needed preposition is available as a property of the
670
container object, namely objInPrep.  This makes it possible to unify
671
the code for the three classes by referring to this property rather
672
than hard-coding the preposition - by doing this, the code for the
673
three subclasses becomes identical, which allows it to be consolidated
674
in a common base class.
675
676
<p>The advantage of this change is that it's no longer necessary to
677
change a specialized container's contents-lister class simply because
678
you want to change the preposition used to describe the relationship
679
between contents and container.  In the past, you had to change
680
<i>both</i> objInPrep and the contents lister.  Now, changing
681
objInPrep is enough - since the default contents listers refer to
682
objInPrep, changes to objInPrep will automatically flow through to the
683
wording in contents listings.
684
685
<p>Because the class structure is the same as before, existing code
686
should work unchanged, and you can still use contents lister
687
customizations to achieve effects beyond the simple wording changes
688
that objInPrep provides, if needed.
689
690
</div>
691
692
<!------------------->
693
<div class=entry>
694
695
<p>The new class ActorHelloTopic makes it easier to
696
create a greeting message for cases where the NPC initiates a
697
conversation through a script.  Place an ActorHelloTopic object
698
anywhere a HelloTopic would go to create a greeting specifically
699
for the case of an NPC-initiated conversation.
700
701
<p>[Update for 3.0.18: disregard the following.  These changes
702
were not effected as described, and weren't quite what was intended.
703
See <a href="#3018-byetopic-convnode">this entry</a> for an update.]
704
705
<p><i>
706
ByeTopic objects can now be used with actors who use conversational
707
states (ConversationReadyState, InConversationState).  In the past,
708
the conversational states largely bypassed the topic-based Goodbye
709
processing, so goodbyes had to be written with the specialized goodbye
710
methods on the state objects.  This made the conversation states
711
harder to use, since it created special cases you had to be aware of.
712
Now, you can set up a goodbye message by locating a ByeTopic within
713
the InConversationState or within any ConvNode.
714
</i>
715
716
</div>
717
718
719
<!------------------->
720
<div class=entry>
721
722
The class ComplexComponent now defines stagingLocations as the lexical
723
parent's (which is normally the ComplexContainer's) location.  This
724
makes it easier to embed a nested room (a platform, booth, etc) as a
725
component of a complex container object, by allowing inbound travel
726
into the nested room to bypass the complex container and move directly
727
between the enclosing location and the component/nested room.  As with
728
other aspects of complex containers, the container and component are
729
meant to look and act like a single object, from the player's
730
perspective, so it's not desirable to treat the container and
731
component as separate objects for the purposes of nested room travel.
732
733
<p>Along the same lines, ComplexContainer now tries to remap the
734
actions StandOn, SitOn, LieOn, Board, and Enter to a suitable
735
component.  These actions are now automatically remapped to the object
736
returned from the new method getNestedRoomDest(), if any.  If that
737
method returns nil, the actions are not remapped after all.
738
739
<p>The new getNestedRoomDest() method of ComplexContainer looks for a
740
suitable component to use as the destination of a nested room travel
741
command.  By default, it first looks to see if the sub-surface
742
component is a NestedRoom object, and if so, returns that; otherwise,
743
it checks the sub-container component, and returns that if that's a
744
NestedRoom; otherwise it returns nil.  This default behavior makes
745
everything automatic for cases where you have exactly one component
746
that's a nested room.  If you want to define more than one nested room
747
within a complex container (for example, a large crate that you can
748
STAND ON and also GET IN), you will need to override
749
getNestedRoomDest() to return the appropriate destination by verb, or
750
you can simply override the dobjFor(action) remapTo() definition to
751
point remap to the correct component.
752
753
</div>
754
755
<!------------------->
756
<div class=entry>
757
758
A bug in the parser sometimes caused "truncated plurals" to be
759
selected ahead of exact matches in a player's answer to a
760
disambiguation question.  By design, the parser prefers an exact match
761
to a singular noun ahead of a partial match to a plural (for example,
762
with the default six-letter truncation, the word "object" in command
763
input would match either the singular "object" or the plural
764
"objects", but the parser assume the singular word was intended
765
because it's an exact match for the input).  However, this principle
766
was being ignored in this case due to the bug.  This has now been
767
corrected.
768
(<a href="http://bugdb.tads.org/view.php?id=0000006">bugdb.tads.org #0000006</a>)
769
770
</div>
771
772
<!------------------->
773
<div class=entry>
774
775
In the past, if a ConvNode was activated via the &lt;.convnode&gt;
776
tag, and the ConvNode's noteActive() method displayed any text, the
777
text displayed within noteActive() appeared out of order in the final
778
output relative to the text containing the &lt;.convnode&gt; tag.
779
This happened because &lt;.convnode&gt; is processed within an output
780
filter, so the entire string containing the &lt;.convnode&gt; had to
781
be processed by the filter before any of it was actually displayed; if
782
any text was displayed in the course of recursively called routines
783
such as noteActive(), that text would as a result show up first in the
784
final output.
785
786
<p>The &lt;.convnode&gt; output filter now captures any text that's
787
displayed in the course of activating a new ConvNode, and re-inserts
788
the text into the stream at the proper point.  This ensures that the
789
text appears in the correct sequence, so it's now safe to display text
790
from within a noteActive() routine.
791
(<a href="http://bugdb.tads.org/view.php?id=0000003">bugdb.tads.org #0000003</a>)
792
793
</div>
794
795
<!------------------->
796
<div class=entry>
797
798
In the past, TIAction verbs (those taking a direct object and an
799
indirect object, such as PUT IN or UNLOCK WITH) had the side effect of
800
clearing the parser's memory of gender-specific pronoun antecedents.
801
For example, after typing "LOOK AT BOB; UNLOCK THE DOOR WITH HIS KEY",
802
the parser would forget that "him" refers to Bob, even though there
803
wasn't anyone else mentioned in the second command to supersede the
804
meaning of "him".  This has been fixed.
805
(<a href="http://bugdb.tads.org/view.php?id=0000020">bugdb.tads.org #0000020</a>)
806
807
</div>
808
809
<!------------------->
810
<div class=entry>
811
812
The Room class now applies a lower level of disambiguation
813
"likelihood" for the Examine action to a remote room than for a room
814
containing the actor.  In the past, the class applied a
815
lower-than-default likelihood for a room containing the actor, on the
816
assumption that a player who types EXAMINE FOO probably means to
817
examine a nearby object rather than the enclosing room, when both are
818
called FOO.  However, there's a third possibility, which is that
819
there's a remote room (i.e., a separate top-level room that's
820
connected to the current location by a sense connection) in scope
821
that's <i>also</i> called FOO.  In these cases, we'd still want to
822
select the nearby object over either room; but in cases where we only
823
have the two rooms to decide between, it seems most likely that the
824
player would want to refer to the enclosing room rather than the
825
remote one.  This new distinction in the likelihood levels of
826
enclosing and remote rooms accomplishes this: the most likely
827
selection is still a nearby non-room object, the next most likely is
828
the enclosing room, and the least likely is a remote room.
829
830
831
</div>
832
833
834
835
<!------------------------------- 3.0.16 --------------------------------->
836
<div class="sepbar"><a name='3016'></a>3.0.16</div>
837
<p><b><i>Released 4/10/2008</i></b>
838
<p>
839
840
<!------------------->
841
<div class=firstentry>
842
843
The new class SimpleLister provides simplified interfaces for creating
844
formatted lists of items.  This class is useful when you just want to
845
create a textual listing, using the standard serial-comma generation
846
and so on, without all the hassle of specifying a sense environment,
847
point of view, etc.  The class also has a method that creates a text
848
string for a listing (rather than displaying the list directly, which
849
is what the base Lister normally does).
850
851
<p>Two concrete instances of SimpleLister are provided, to further
852
simplify particular listings: objectLister, which can be used to
853
format a list of simulation objects; and stringLister, which can be
854
used to format a list of string values.
855
856
</div>
857
858
<!------------------->
859
<div class=entry>
860
861
Commands of the form "X, Y", where both X and Y were words not in the
862
game's dictionary, caused a run-time error ("nil object reference").
863
This was due to a library bug in the code that resolves the actor
864
object when giving orders to an actor ("BOB, GO EAST").  This has been
865
corrected.
866
   
867
</div>
868
869
<!------------------->
870
<div class=entry>
871
872
The Goal object has a new property, goalFullyDisplayed, that the hint
873
system automatically sets to true upon displaying the last hint in the
874
Goal's menu list.  This can be used, for example, to close a hint for
875
a red herring after the player's seen the full list of hints; this
876
might be desirable to remove clutter from the menu, since the player
877
probably won't worry about an object again once it's been revealed
878
that it's just a red herring.
879
880
</div>
881
882
<!------------------->
883
<div class=entry>
884
885
The templates for TravelMessage, NoTravelMessage, and DeadEndConnector
886
now accept an event list (given as a list in square brackets) in lieu
887
of a double-quoted message string.  These classes were already mixable
888
(via multiple inheritance) with EventList, so this change simply makes
889
it more convenient to define instances when using this capability.
890
891
</div>
892
893
<!------------------->
894
<div class=entry>
895
896
Top-level rooms (i.e., Room objects) didn't properly handle ENTER
897
commands (e.g., ENTER HALLWAY) when attempted from a separate
898
top-level room connected via a sense connector.  The ENTER handling
899
for Room incorrectly assumed that only one top-level room was in scope
900
at a time, which isn't true when rooms have sense connections.  The
901
handler also failed to handle the simpler situation where the actor
902
was in a nested room within the target room.
903
904
<p>The Room dobjFor(Enter) handler has been improved to handle
905
such situations.  The new handling is as follows:
906
907
<ul>
908
909
<li>If the actor is already <i>directly</i> in the target room (for
910
example, the player types ENTER HALLWAY while already in the hall),
911
the behavior is as before ("You're already in the hallway").
912
913
<li>If the actor is <i>indirectly</i> in the target room (for example,
914
the PC is sitting in a chair in the hall, and types ENTER HALLWAY),
915
the command is replaced with GET OUT OF <i>outermost nested room
916
containing actor within target room</i>.
917
918
<li>If the actor is in a separate top-level room, <i>and</i> there's
919
a travel connector from the actor's current location to the target
920
room, the command is replaced with TRAVEL VIA <i>connector</i>.
921
922
<li>Otherwise, the command fails with the message &amp;whereToGoMsg
923
("You'll have to say which way to go").
924
925
</ul>
926
927
</div>
928
929
<!------------------->
930
<div class=entry>
931
932
In the past, when NestedRoom.checkMovingActorInto() decided it had to
933
perform an implied action to move the actor into the nested room, the
934
routine assumed that the action failed if the actor didn't end up in
935
the nested room <i>and</i> in the room's default posture.  This
936
condition does hold for the library NestedRoom subclasses when the
937
defaults are inherited, but overriding either the default posture or
938
the implied command for a particular instance can make the condition
939
fail.  When the condition fails, the routine infers that the implied
940
action failed, and terminates the whole command.
941
942
<p>This condition - specifically, the test for posture - is overly
943
strict.  The routine isn't documented as guaranteeing the default
944
posture, and in fact it never did guarantee the default posture
945
anyway, as the implied action was always bypassed if the actor's
946
location was initially correct, regardless of posture.
947
948
<p>So, the condition has now been changed to remove the default
949
posture check.  The implied command (if any) is now considered
950
successful if the actor is directly in the nested room afterward.
951
952
</div>
953
954
<!------------------->
955
<div class=entry>
956
957
Two changes to BasicChair simplify the way the "get in" commands for
958
the object and its subclasses are implemented.
959
960
<p><b>First</b>, the tryMovingIntoNested() routines in BasicChair and
961
its subclasses have been unified into a single base-class method.  In
962
the past, each BasicChair subclass overrode tryMovingIntoNested() to
963
perform the implied action matching the subclass type - SitOn for
964
BasicChair, LieOn for BasicBed, StandOn for BasicPlatform.
965
966
<p>Now, the overrides have been removed, and the functionality has
967
been been unified into a single method on BasicChair that the
968
subclasses all inherit.  The BasicChair version of the method handles
969
all of the subclasses by deferring to the default posture object (as
970
returned from the defaultPosture property).
971
972
<p><b>Second</b>, the dobjFor(Board) definitions have been unified
973
in a single BasicChair definition, rather than requiring overrides
974
in each subclass as in the past.  As with tryMovingIntoNested(),
975
the dobjFor(Board) definition in BasicChair now calls upon the
976
default posture object to carry out the appropriate command.  This
977
removes the need to override dobjFor(Board) in each subclass.
978
979
<p>The benefit of these changes is that there's less to override when
980
creating a custom type of BasicChair subclass.  Setting the
981
defaultPosture also automatically takes care of setting the implied
982
action for "get in" and the mapped action for "board", since
983
tryMovingIntoNested() and dobjFor(Board) now choose the sub-action
984
that matches the default posture.  Of course, if for some reason you
985
want these actions to differ from what the default posture selects,
986
you can still override tryMovingIntoNested() and/or dobjFor(Board) to
987
achieve whatever special effects you want.  For typical objects where
988
the two match, though, these changes means less work is needed to keep
989
everything in sync.
990
991
</div>
992
993
<!------------------->
994
<div class=entry>
995
996
The "standing" posture object's setActorToPosture() method has been
997
changed slightly.  In the past, the routine performed an intransitive
998
Stand action, which causes the actor to stand up in whatever location
999
it's currently occupying.  This was at odds with the specification of
1000
the method: the routine should not only make the actor stand up, but
1001
make the actor stand in a given location; the old version ignored the
1002
target location.  The routine now does use the target location, and
1003
executes a transitive StandOn action with the target location as
1004
direct object.
1005
1006
<p>The old implementation was the way it was because the transitive
1007
StandOn action didn't always work properly when applied to top-level
1008
rooms.  However, the handling of StandOn for top-level rooms has since
1009
been improved, so this is now a viable implementation.  This makes the
1010
method work consistently with its specification and with the
1011
corresponding methods in the other pre-defined posture objects.
1012
1013
</div>
1014
1015
<!------------------->
1016
<div class=entry>
1017
1018
The Decoration class now overrides the SEARCH action so that it uses
1019
the standard Thing handling, to be consistent with the way LOOK IN is
1020
handled.  In the past, SEARCH instead was handled by the Decoration
1021
catch-all verb handler, which shows the generic "that's not important"
1022
message.  This led to different default Decoration behavior for SEARCH
1023
vs LOOK IN, which was inconsistent with the library's usual default
1024
treatment of the two actions as synonymous.
1025
1026
</div>
1027
1028
<!------------------->
1029
<div class=entry>
1030
1031
The English library's typographical output filter object
1032
(typographicalOutputFilter) ordinarily adds an "en" space (a space
1033
that's slightly wider than a normal inter-word space) after any
1034
sentence-ending punctuation, such as a period or question mark.  This
1035
produces looser spacing between sentences, which some people find
1036
easier to read.  However, it had an undesirable side effect, which was
1037
to add the same spacing after honorific abbreviations like Mr. and
1038
Mrs. - these look exactly like sentence endings, as far as the simple
1039
substitution rule was concerned.
1040
1041
<p>The filter now specifically looks for a pre-defined set of
1042
abbreviations, and suppresses the extra spacing when it finds one.
1043
The abbreviations are given by the property
1044
typographicalOutputFilter.abbreviations - to change or add to the set
1045
of abbreviations, modify typographicalOutputFilter to change this
1046
property.  (Note that this property is only evaluated once, at program
1047
start-up, so changing it on the fly won't have any effect.  If you do
1048
want to modify the set of abbreviations dynamically, you'll have to
1049
instead update typographicalOutputFilter.abbrevPat to use a new
1050
RexPattern object with the new set of abbreviations.)
1051
1052
</div>
1053
1054
<!------------------->
1055
<div class=entry>
1056
1057
DistanceConnector now allows moving objects through the connector via
1058
moveInto - in particular, DistanceConnector now overrides
1059
checkMoveThrough() to return a "success" indication.
1060
In the past, DistanceConnector inherited checkMoveThrough() from
1061
SenseConnector, which disallowed a move via moveInto() if the distance
1062
connector was involved. 
1063
1064
<p>In the abstract, there's usually no good reason that an object
1065
can't be moved through a distance connector.  The only reason to
1066
disallow it might be that the distance involved is so great that it
1067
would take an impractical amount of time to complete the move.
1068
1069
<p>More to the point, though, player commands will generally disallow
1070
this kind of operation for reasons of reachability - a touchObj
1071
precondition is involved for any basic command that moves an object
1072
from one container to another (TAKE, DROP, PUT IN, PUT ON, etc), and
1073
that precondition will fail separately because the distance object is
1074
unreachable.  Because of this, a moveInto() involving a distance
1075
connector is almost certainly due to a programmatic (scripted)
1076
operation, rather than a basic player command.  In the past, you could
1077
work around this by calling moveIntoForTravel() instead of moveInto(),
1078
but this was a needless complication.  This change allows moveInto()
1079
to succeed even if a distance connector is involved.
1080
1081
</div>
1082
1083
<!------------------->
1084
<div class=entry>
1085
1086
The ShuffledEventList object has a new property, suppressRepeats, that
1087
lets you control whether or not a given event can occur twice in a
1088
row.  This property corresponds to the suppressRepeats property of
1089
the ShuffledList object.
1090
1091
<p>By default, this is set to true, which yields the former behavior.
1092
You can set this to nil if you don't want to suppress repeats.  With
1093
very small lists (of three or four elements), the suppression of
1094
repeats sometimes makes the result sequence look fairly un-random,
1095
because the no-repeats constraint reduces the number of available
1096
permutations.  If you see output for a small event list that doesn't
1097
look random enough, you might try setting suppressRepeats to nil to
1098
see if that produces more pleasing results.
1099
1100
</div>
1101
1102
<!------------------->
1103
<div class=entry>
1104
1105
ShuffledList now ignores suppressRepeats for a two-element list.  If
1106
the list has only two elements, and repeats aren't allowed, the list
1107
will necessarily yield the predictable sequence A-B-A-B..., which
1108
defeats the purpose of the shuffled list.
1109
1110
</div>
1111
1112
<!------------------->
1113
<div class=entry>
1114
1115
The Lockable class's dobjFor(Open) check() method now inherits the
1116
default handling.  Since Lockable is designed to be used as a mix-in
1117
class, this addition ensures that any additional Open checks inherited
1118
from other superclasses are properly invoked.
1119
1120
</div>
1121
1122
<!------------------->
1123
<div class=entry>
1124
1125
The comment pre-parser object (commentPreParser) now sets a runOrder
1126
value that's lower than the default, so that it runs before other
1127
pre-parsers that inherit the default runOrder.  In most cases, it's
1128
unnecessary (and even potentially problematic) to run comments through
1129
other pre-parsers, since most are designed to parse the usual sorts of
1130
command syntax, not the free-form text allowed in comments.  Running
1131
the comment pre-parser first effectively bypasses other pre-parsers
1132
when a comment is encountered, since the comment pre-parser halts
1133
further processing of the command when it detects that the command is
1134
actually a comment.
1135
1136
</div>
1137
1138
<!------------------->
1139
<div class=entry>
1140
1141
In the past, if an actor returned nil from obeyCommand(), the parser
1142
ignored the command for the purposes of the AGAIN command.  A
1143
subsequent AGAIN command in this case simply repeated the
1144
<i>previous</i> command - the one just before the refused order.  This
1145
has been corrected; the parser now remembers a command for AGAIN even
1146
if the actor to whom the command is directed refuses it.
1147
1148
</div>
1149
1150
<!------------------->
1151
<div class=entry>
1152
1153
Thing.setGlobalParamName() didn't correctly delete any previous name
1154
from the global table.  (This would only have been a problem if you
1155
used the method more than once on a particular object, to change the
1156
object's global parameter name on the fly, which seems highly
1157
unlikely.)  This has been corrected.
1158
1159
</div>
1160
1161
1162
<!------------------------------- 3.0.15.3 --------------------------------->
1163
<div class="sepbar"><a name='3015c'></a>3.0.15.3</div>
1164
<p><b><i>Released 11/2/2007</i></b>
1165
<p>
1166
<!------------------->
1167
<div class=firstentry>
1168
   <i>There are no library changes in this release.</i>
1169
</div>
1170
1171
1172
<!------------------------------- 3.0.15.2 --------------------------------->
1173
<div class="sepbar"><a name='3015b'></a>3.0.15.2</div>
1174
<p><b><i>Released 9/13/2007</i></b>
1175
<p>
1176
1177
<!------------------->
1178
<div class=firstentry>
1179
1180
NonObviousVerifyResult.resultRank is now defined as the same value as
1181
IllogicalVerifyResult.resultRank.  This makes the parser treat
1182
illogical and non-obvious objects as equivalent in cases of ambiguity,
1183
so that the parser won't choose one over the other.  In the past,
1184
non-obvious objects were ranked lower than illogical objects, which
1185
caused the parser to choose an illogical object over a non-obvious
1186
object in cases of ambiguity.  This didn't quite make sense; for the
1187
purposes of choosing among ambiguous objects, non-obvious objects
1188
really should be treated as equivalent to ordinarily illogical
1189
objects, since the point of the non-obvious designation is that the
1190
object appears at first glance to be illogical for a given verb.
1191
1192
</div>
1193
1194
<!------------------->
1195
<div class=entry>
1196
1197
The parser now incorporates Michel Nizette's vocabLikelihood
1198
extension.  This extension lets each object set an "intrinsic
1199
likelihood" value that affects how the parser chooses among ambiguous
1200
objects.  When the parser can't tell the difference between two
1201
objects using the normal 'verify' procedure, it compares the
1202
vocabLikelihood properties of the two objects, and chooses the one
1203
with the higher value if they differ.  This makes it easier to
1204
fine-tune the disambiguation process to reduce unnecessary prompting.
1205
1206
</div>
1207
1208
<!------------------->
1209
<div class=entry>
1210
1211
SensoryEmanation.endEmanation() now resets displayCount to nil.
1212
displayCount was documented as being automatically reset when a period
1213
of continuous presence ended, but in the past no actual resetting was
1214
done.  We set the value to nil, rather than to 0 or 1, to make it more
1215
obvious (when debugging, for example) that the object is not currently
1216
in scope.
1217
1218
</div>
1219
1220
<!------------------->
1221
<div class=entry>
1222
1223
The English library now defines suitable custom objInPrep,
1224
actorInPrep, and actorOutOfPrep values for Surface, Underside, and
1225
RearContainer.  This ensures that the default messages produce
1226
reasonable relational descriptions when referring to the contents of
1227
these specialized container types.  (In the past, only
1228
Surface.objInPrep was suitably customized.)
1229
1230
</div>
1231
1232
<!------------------->
1233
<div class=entry>
1234
1235
BasicOpenable.tryImplicitRemoveObstructor() now only attempts an
1236
implied Open if the object is closed.  When the object is already
1237
open, the routine now does nothing.  This change is necessary because
1238
objects can conceivably create an obstruction even if they're already
1239
open: once the object's open, if it's still creating an obstruction,
1240
another implied Open would be pointless (and, in fact, could cause
1241
an infinite loop).
1242
1243
</div>
1244
1245
<!------------------->
1246
<div class=entry>
1247
1248
The new Thing method isOrIsIn(obj) returns true if 'self' is either
1249
inside 'obj' or equal to 'obj'.  This is useful for cases where you
1250
want to check if a given object is anywhere within another object's
1251
containment tree, <i>including</i> the other object itself.
1252
   
1253
</div>
1254
1255
<!------------------->
1256
<div class=entry>
1257
1258
When a MultiLoc object is the point-of-view object in a sense
1259
calculation, it now connects all of its multiple containers to the
1260
scope in addDirectConnections().  In the past, a MultiLoc's containers
1261
were only considered part of the scope when the point of view was
1262
<i>inside</i> the MultiLoc, but it makes sense for the MultiLoc itself
1263
to be the same way, since it inherently "sees" all of its containers.
1264
1265
</div>
1266
1267
<!------------------->
1268
<div class=entry>
1269
1270
LocateInParent is now defined as a class.  (It was always meant to be,
1271
but the definition lacked an explicit 'class' keyword in past version.)
1272
1273
</div>
1274
1275
1276
<!------------------------------- 3.0.15.1 --------------------------------->
1277
<div class="sepbar"><a name='3015a'></a>3.0.15.1</div>
1278
<p><b><i>Released 7/19/2007</i></b>
1279
<p>
1280
1281
<!------------------->
1282
<div class=firstentry>
1283
1284
<b>Compatibility warning:</b> The message property cannotTalkToSelf
1285
has been renamed to cannotTalkToSelfMsg, for consistency with other
1286
message property names.  (You should search your existing game code
1287
and update any references to the old name to use the new name
1288
instead.)
1289
1290
</div>
1291
1292
<!------------------->
1293
<div class=entry>
1294
1295
<p>The new gameMain property beforeRunsBeforeCheck lets you control
1296
the relative ordering of the "check" phase and "before" notifiers.
1297
1298
<p>In the past, the library always ran the "before" notifiers -
1299
beforeAction and roomBeforeAction - <i>before</i> running the check()
1300
handlers for the objects involved in the action.  To ensure
1301
compatibility, the default setting for the new property is
1302
beforeRunsBeforeCheck = true - this causes "before" to run before
1303
check(), as it always has.
1304
1305
<p>However, in many ways, it's more logical and practical to run the
1306
check() phase first first, and <i>then</i> run the "before" notifiers.
1307
This ordering allows the "before" handlers to assume that the action
1308
is more or less committed to running to completion, since they know
1309
that the check() phase has already tested the action and allowed
1310
it to proceed.  The most common use of "before" handlers is to carry
1311
out side effects of an action, so by running all of the check() tests
1312
first, the "before" handlers can more confidently invoke their side
1313
effects, without worrying that the action will later fail due to a
1314
check() condition.
1315
1316
<p>Now, you can never truly call an action "committed" until it's been
1317
fully carried out, since even a "before" handler can conceivably
1318
cancel a command (with "exit", for instance).  You could set up a
1319
situation where an action is affected by two "before" handlers, and
1320
the one that runs later cancels the command - thus invalidating any
1321
assumption in the first one that the command is committed.  However,
1322
this is relatively unusual, and in any case it's under your control:
1323
if you don't use "before" handlers to cancel commands, it won't occur.
1324
1325
<p>If you want to use the new alternative ordering, where "check" runs
1326
before the "before" notifications, simply set beforeRunsBeforeCheck to
1327
nil in your gameMain object.  Some authors have tested this ordering
1328
with existing games and found it to work well with existing code, but
1329
be aware that you could trigger subtle changes - you might have
1330
unknowingly created dependencies on the relative ordering of check()
1331
and "before" that will only show up under certain conditions.  We
1332
therefore recommend using the new alternative ordering only for new
1333
code or for projects that are relatively early in their development
1334
cycle, to ensure thorough testing of the new ordering.
1335
1336
</div>
1337
1338
<!------------------->
1339
<div class=entry>
1340
1341
ThingState now allows tokens to be shared among multiple states
1342
associated with the same object.  In the past, state words had to be
1343
unique among an object's states: it wasn't possible to have a set of
1344
states such as "unpainted", "painted red", and "painted blue", because
1345
it was invalid for "painted" to appear in two states.  This sort of
1346
sharing is now allowed.
1347
1348
<p>The old rule was that a word could match an object only if the word
1349
didn't appear in any of the object's <b>other</b> (i.e., non-current)
1350
ThingState token lists.  The new rule is that a word can match an
1351
object if (a) the word appears in the object's <b>current</b>
1352
ThingState token list, <b>or</b> (b) the word <b>doesn't</b> appear in
1353
any of the object's <b>other</b> ThingState token lists.  Condition
1354
(a) is what's new; it allows words to be shared among states by
1355
allowing a word to match the current state as long as it's in the
1356
current state's list, regardless of whether it appears in other
1357
states' lists.
1358
1359
</div>
1360
1361
<!------------------->
1362
<div class=entry>
1363
1364
In the English library, when a command triggers a chain of several
1365
implied actions, the announcement for the implied actions now adds
1366
the word "then" in each conjunction: "(first standing up, <b>then</b>
1367
taking the box, <b>then</b> opening it)".  In the past, "then"
1368
appeared only in the final conjunction; most people find it reads
1369
more naturally to use "then" in each conjunction.
1370
1371
</div>
1372
1373
<!------------------->
1374
<div class=entry>
1375
1376
The English library now uses the adjustDefaultObjectPrep() mechanism
1377
to generate implied action announcements.  This means that verbs like
1378
SitOn and GetOutOf will use object-specific prepositions when they're
1379
announced as implied actions: "(first sitting on the bench)" vs
1380
"(first sitting in the car)".
1381
1382
</div>
1383
1384
<!------------------->
1385
<div class=entry>
1386
1387
The actions GetOutOf and GetOffOf now adjust the prepositions in their
1388
generated verb phrases according to the actorOutOfPrep definition for
1389
the direct object.
1390
1391
</div>
1392
1393
<!------------------->
1394
<div class=entry>
1395
1396
AccompanyingInTravelState.initiateTopic() now defers to the next state
1397
object.  Since the in-travel state is designed to be ephemeral, it's
1398
unlikely that one of these would actually contain its own initiated
1399
topics, so in almost all cases the desired topic would come from the
1400
state that the actor will be in following the travel.
1401
1402
</div>
1403
1404
<!------------------->
1405
<div class=entry>
1406
1407
The library now defines a simple template for ShuffledList.  The new
1408
template takes a single list parameter giving the value list.
1409
1410
</div>
1411
1412
<!------------------->
1413
<div class=entry>
1414
1415
ListGroupCustom now defines groupDisplaysSublist = nil by default.
1416
This type of group is intended mainly for cases where you want to
1417
display a collective message to describe the group, rather than
1418
listing its elements individually, so we usually don't want the
1419
inclusion of a ListGroupCustom message to trigger the "long list"
1420
format (i.e., with semicolons) in the overall list.  This change
1421
makes this behvior the default.
1422
1423
</div>
1424
1425
<!------------------->
1426
<div class=entry>
1427
1428
Non-physical CollectiveGroup objects (i.e., those with 'nil'
1429
locations) didn't work when the associated individuals were MultiLoc
1430
or SenseConnector objects. This has been corrected.
1431
1432
</div>
1433
1434
<!------------------->
1435
<div class=entry>
1436
1437
Actor.knowAbout() now considers an object to be known if it's
1438
<i>currently</i> in sight.  In the past, an object was known if it was
1439
specifically marked as known, or it was marked as having been
1440
previously seen.  For the most part, an object that's currently
1441
visible will also be marked as having been previously seen, since this
1442
marking occurs whenever a Look command or travel to a new location
1443
lists an object.  However, if an object comes into scope (via
1444
moveInto) while an actor is in a given location, the object won't be
1445
marked as having been seen until the next Look command or subsequent
1446
travel away from and then back to the location.
1447
1448
<p>This change corrects a subtle problem that involved possessive
1449
phrases in commands.  In the past, an object that just came into scope
1450
was excluded from matching a possessive noun phrase under certain
1451
circumstances, such as in the response to a disambiguation question.
1452
This should no longer occur.
1453
1454
</div>
1455
1456
<!------------------->
1457
<div class=entry>
1458
1459
In the past, the library <i>seemed</i> to allow commands like PUSH TV
1460
INTO BOX (i.e., commands to push a pushable object into a nested
1461
room), but on closer inspection it didn't really carry them out:
1462
instead, it carried out only the underlying basic travel command,
1463
without actually moving the object supposedly being pushed around.
1464
The library now rejects PUSH INTO <i>nested room</i> commands with a
1465
new message, &amp;cannotPushObjectNested ("You can't push the TV
1466
there").
1467
1468
<p>The library rejects these commands by default because we think
1469
it'll be relatively rare that games will need to allow them.  Given
1470
that, it didn't seem worth complicating things by adding a bunch of
1471
new methods to provide generalized support, and we also didn't want to
1472
introduce that much new code at the current point in the release
1473
cycle.
1474
1475
<p>However, the library does now provide a new hook that will make it
1476
easier for games to implement PUSH INTO <i>nested</i> commands if they
1477
need to.  The new hook will also make it possible to implement riding
1478
vehicles into nested rooms, which wasn't previously possible.  The new
1479
hook is a new Traveler method, travelerTravelWithin().
1480
1481
<p>This new method is called on the Traveler object when a nested-room
1482
travel command (GET IN, STAND ON, SIT ON, LIE ON, PUSH X INTO, etc) is
1483
performed.  In simple cases, the Traveler is simply the Actor
1484
performing command.  However, if the actor is riding in a Vehicle, the
1485
Traveler is the Vehicle object; and if the command is a PUSH travel
1486
command, such as PUSH TV INTO BOX, the Traveler is a special ephemeral
1487
object, of class PushTraveler, created just for the command.
1488
1489
<p>The library provides default implementations of the new hook method
1490
for Actor, Vehicles, and PushTraveler.  For Actor, the method simply
1491
does the same thing that travelWithin() used to do, so existing code
1492
will work as it did before.  For Vehicle, the method calls the same
1493
method on the Actor, so again it will work as it used to.  For
1494
PushTraveler, the method simply terminates the command with the new 
1495
message &amp;cannotPushObjectNested.
1496
1497
<p>If you want to allow pushing objects into nested rooms, you'll need
1498
to modify PushTraveler.travelerTravelWithin() to do basically the same
1499
thing that PushTraveler.travelerTravelTo() does.  You'll probably want
1500
to set up a new set of notification methods parallel to
1501
beforeMovePushable() and movePushable() - you could just use those
1502
same routines, but you'll probably want to set up new custom
1503
nested-room versions instead, since the conditions and messages will
1504
probably need to be different for nested rooms from those used for
1505
room-to-room travel.
1506
1507
<p>Note that you could also take advantage of the new method to allow
1508
an actor to ride a vehicle into a nested room.  The default handling
1509
in Vehicle defers to the underlying Actor, and the actor performs the
1510
travel as though the Vehicle were any other nested room - which means
1511
that the actor gets out of the vehicle, then gets into the new nested
1512
room.  If you instead wanted this type of command to mean "ride
1513
vehicle into nested room," you can override travelerTravelWithin() on
1514
the vehicle, so that the method moves the Vehicle itself into the new
1515
nested room.  (You'll also have to set up preconditions that move the
1516
vehicle to the proper staging locations using the same rules that are
1517
used for actors, which could take a little work - that's the main
1518
reason the library doesn't support it out of the box yet.)
1519
1520
</div>
1521
1522
<!------------------->
1523
<div class=entry>
1524
1525
In the past, if an NPC was using AccompanyingState to follow around
1526
the player character, and the pair went through an AutoClosingDoor,
1527
the door was reported as having closed twice during the turn -
1528
once for each actor going through.  AutoClosingDoor now skips the
1529
auto-closing step if the actor going through is in an accompanying
1530
state.
1531
1532
</div>
1533
1534
<!------------------->
1535
<div class=entry>
1536
1537
The parser's "OOPS" mechanism had a problematic interaction with
1538
literal phrases that showed up under certain conditions.  In
1539
particular, if the player entered a command that caused some kind of
1540
follow-up question, such as a disambiguation query ("which book do you
1541
mean...") or missing-object prompt ("what do you want to unlock it
1542
with?"), <b>and</b> the player chose to ignore the follow-up question
1543
and instead just enter a new command, <b>and</b> the new command
1544
contained a literal phrase ("type asdf on keypad", say), the OOPS
1545
mechanism was overly aggressive in deciding the command contained a
1546
typo.
1547
1548
<p>The root of the problem was that follow-up questions are parsed
1549
according to their own special grammars, which are much more limited
1550
than the full grammar used at the main command prompt.  Normally, when
1551
the player responds with something that doesn't match one of these
1552
special grammars, the parser assumes the player intended to bypass the
1553
follow-up question and just enter a new command.  However, if parser
1554
manages to find a non-dictionary word in the player's input, it
1555
invokes the OOPS mechanism to see if the player actually intended to
1556
answer the follow-up question but made a typographical error entering
1557
the response.  The problem is that if the player entered a
1558
literal-phrase verb, the presence of a non-dictionary word
1559
<i>doesn't</i> necessarily imply a typographical error.  For normal
1560
commands (as opposed to follow-up questions), this isn't an issue,
1561
because the parser finds the literal when matching against the full
1562
grammar.  For follow-up questions, though, the parser never noticed
1563
the literal-phrase interpretation of the input, since it wasn't
1564
matching against the full grammar, so it prematurely decided that the
1565
input as mis-typed.
1566
1567
<p>The OOPS mechanism now makes an extra check when presented with a
1568
non-dictionary word in the response to a follow-up question.  Before
1569
deciding that the input really does contain a typo, the OOPS mechanism
1570
first checks the input to see if it matches anything in the full
1571
command-line grammar; if the parser finds a match, it assumes that the
1572
entry was meant as a brand new command, and so it bypasses the
1573
follow-up question and re-parses the input as a new command.
1574
1575
</div>
1576
1577
<!------------------->
1578
<div class=entry>
1579
1580
In the past, calling getOrigTokenList() on an EventAction object
1581
caused a run-time error.  This was because EventActions don't have the
1582
token list data that the parser normally attaches when creating an
1583
Action to represent a parsed command line, which in turn is because
1584
these actions aren't created from command parsing but are instead
1585
"synthetic" actions, created internally by the library for bookkeeping
1586
purposes.  (This same problem might have affected other synthetic
1587
actions as well, but it's only known to have shown up with
1588
EventActions.)
1589
1590
<p>This has been corrected.  Action.getOrigTokenList() now checks to
1591
make sure there's a parser token list attached to the action, and if
1592
not, the method return the parent action's token list; and if there's
1593
no parent action, the method simply returns an empty list.
1594
1595
</div>
1596
1597
<!------------------->
1598
<div class=entry>
1599
1600
HermitActorState now sets its property limitSuggestsion to true by
1601
default, to prevent the TOPICS command from displaying any topic
1602
suggestions from the actor or conversation node.  This is desirable
1603
because the hermit state effectively blocks any topics defined outside
1604
the state: the whole point of the state is that it makes the actor
1605
essentially unresponsive to conversational overtures.  So there's
1606
generally no point in offering topic suggestions while the actor is in
1607
the state.
1608
1609
<p>In some cases, you might want to override this for a particular
1610
hermit state object.  In particular, if it's not outwardly obvious
1611
that the actor will be unresponsive, you might still want to allow
1612
suggestions, since the player has no way of knowing that the actor
1613
won't respond to questions until she attempts asking them.  Similarly,
1614
if the hermit state is expected to persist for a short time only, you
1615
might want to continue to allow suggestions so that the player knows
1616
there are useful topics to explore when the actor becomes responsive
1617
again.
1618
1619
</div>
1620
1621
<!------------------->
1622
<div class=entry>
1623
1624
ByeTopic now overrides impliesGreeting to suppress any implied HELLO
1625
greeting.  This means that if the player explicitly says GOODBYE to an
1626
NPC, and no conversation is in progress, the goodbye response will be
1627
displayed by itself, without an implied greeting exchange.  In the
1628
past, ByeTopic inherited the default 'true' value for impliesGreeting,
1629
so saying GOODBYE to an NPC outside of a conversation caused an
1630
implied greeting, followed immediately by the explicit goodbye
1631
response.  In most cases, this ended up looking pretty strange - not
1632
only was the self-canceling HELLO-GOODBYE exchange odd on its face,
1633
but in most cases the implied greeting also looked redundant from the
1634
player's perspective, because a player tended to say GOODBYE
1635
explicitly only when she was under the impression that some kind of
1636
conversational interaction was already under way.
1637
1638
</div>
1639
1640
<!------------------->
1641
<div class=entry>
1642
1643
In the past, conversation-flow problems sometimes occurred if a topic
1644
changed its "isConversational" status as a side effect of showing the
1645
response for the topic.  This was because
1646
ActorTopicDatabase.showTopicResponse() waited until after invoking the
1647
response to determine whether the response should affect the
1648
conversation flow, so the status change side effect caused
1649
showTopicResponse() to use the new setting - meant for the next
1650
response - rather than the setting for the response it actually
1651
showed.  This has been corrected; showTopicResponse() now makes its
1652
determination based on the isConversational status as it stands just
1653
before invoking the response.
1654
   
1655
</div>
1656
1657
<!------------------->
1658
<div class=entry>
1659
1660
The finishGameMsg() function now explicitly runs the score notifier
1661
daemon before it displays the end-of-game message.  This ensures that
1662
the usual score-change message is displayed if any points were awarded
1663
in the course of the action that triggered the end of the game.
1664
Without the explicit invocation, the notifier daemon wouldn't
1665
typically get a chance to show a notification for the final point
1666
award: the notification is normally shown just before the next command
1667
prompt after points are awarded, and at the end of the game there's
1668
not usually another command prompt forthcoming.
1669
1670
</div>
1671
1672
<!------------------->
1673
<div class=entry>
1674
1675
In the English library, inlineListingContentsLister didn't always
1676
generate correct verb agreement for its prefix message for a "wide"
1677
listing ("You are carrying tongs (which <b>contains</b> ...)").
1678
This has been corrected.
1679
1680
</div>
1681
1682
<!------------------->
1683
<div class=entry>
1684
1685
In the past, searching a RoomPart nominally containing a RoomPartItem
1686
sometimes caused a "nil object reference" run-time error.  This was
1687
due to a missing point-of-view object setting; the code where the
1688
error occurred now applies a default POV of the command actor when
1689
no explicit POV is set.
1690
1691
</div>
1692
1693
<!------------------->
1694
<div class=entry>
1695
1696
Container and Openable objects now apply a touchObj precondition to
1697
the Search action.  This requires that the actor be able to reach the
1698
object in order to search it.  This change is intended to better
1699
enforce the idea that searching a container involves some actual
1700
physical manipulation, such as shifting the contents around to look
1701
behind or under things, momentarily removing contents to see what's
1702
underneath, and so on.  The actor at least has to be able to reach the
1703
object to perform this kind of manipulation.
1704
   
1705
</div>
1706
1707
<!------------------->
1708
<div class=entry>
1709
1710
In the past, AGAIN didn't work properly when used to repeat a FOLLOW
1711
command involving an NPC using the "guided tour" mechanism (the
1712
TourGuide and GuidedTourState classes).  This was due to a subtle
1713
turn-timer problem with AGAIN that affected commands like FOLLOW that
1714
use nested or replacement actions in the course of their execution.
1715
This problem was observed in the FOLLOW/AGAIN situation, but could
1716
also have affected other commands.  The root problem has been
1717
corrected.
1718
1719
</div>
1720
1721
1722
1723
<!------------------------------- 3.0.15 --------------------------------->
1724
<div class="sepbar"><a name='3015'></a>3.0.15</div>
1725
<p><b><i>Released 3/8/2007</i></b>
1726
<p>
1727
1728
<!------------------->
1729
<div class=firstentry>
1730
1731
The Follow action has always adjusted the scope list to include any
1732
NPCs that the target actor remembers having seen leave, whether or not
1733
they're still within sight.  This allows you to FOLLOW a character
1734
who's no longer present - the whole point of FOLLOW would be defeated
1735
if this weren't possible, after all.  However, in the past, this scope
1736
list expansion created duplicate entries in the scope list if an actor
1737
with a "follow memory" was also still physically present - the actor
1738
was added to the scope list once for ordinary visibility, then again
1739
for the "follow memory."  This duplication caused problems in some
1740
situations, since other parts of the library expect the scope list to
1741
contain only unique entries.  The Follow action now ensures that the
1742
list remains unique after its additions.
1743
1744
</div>
1745
1746
<!------------------------------- 3.0.14 --------------------------------->
1747
<div class="sepbar"><a name='3014'></a>3.0.14</div>
1748
<p><b><i>Released 2/9/2007</i></b>
1749
<p>
1750
There are no library changes in TADS 3.0.14.
1751
1752
1753
<!------------------------------- 3.0.13 --------------------------------->
1754
<div class="sepbar"><a name='3013'></a>3.0.13</div>
1755
<p><b><i>Released 1/19/2007</i></b>
1756
<p>
1757
1758
<!------------------->
1759
<div class=firstentry>
1760
1761
The adv3 English library has a new option setting for the parser's
1762
truncation length.  The truncation length has always been customizable
1763
in the low-level system objects that the parser uses to look up and
1764
match vocabulary words, but the library didn't formerly provide a good
1765
way for games to override <i>its</i> truncation length setting.  In
1766
effect, the truncation length was hard-coded into the English library,
1767
and the only way for authors to change it was to edit en_us.t; most
1768
authors would rather not do that because of the hassle of merging
1769
their own changes into future library updates.
1770
1771
<p>The new setting is in gameMain.parserTruncLength.  The default
1772
setting is 6 characters - this is the same as the English parser's old
1773
hard-wired setting, so existing code will behave the same as it did in
1774
the past.
1775
1776
<p>As part of this change, the new method
1777
languageGlobals.setStringComparator() lets you change the active
1778
string comparator dynamically.  You can use this method if you want to
1779
change the truncation length, or other comprator settings, on the fly
1780
during the game.
1781
1782
</div>
1783
1784
<!------------------->
1785
<div class=entry>
1786
1787
The English library now allows a TAction VerbRule to specify a custom
1788
preposition for a default object announcement, overriding the
1789
preposition coded in the verbPhrase.  This is useful for a few verbs
1790
where the preposition tends to vary according to the direct object.
1791
For example, SIT might use ON in some cases but IN for other cases:
1792
"on the stool" vs "in the car."
1793
1794
<p>To accomplish this, TAction.announceDefaultObject() first parses
1795
the verbPhrase to get the standard preposition, then calls a new
1796
method on self, adjustDefaultObjectPrep(prep, obj).  'prep' is the
1797
default preposition from the verbPhrase, and 'obj' is the direct
1798
object of the command.  The routine returns the new preposition
1799
string.  The default implementation simply returns 'prep', but
1800
the StandOn, SitOn, and LieOn actions override this to return the
1801
direct object's actorInPrep.
1802
1803
</div>
1804
1805
<!------------------->
1806
<div class=entry>
1807
1808
InitiateTopics can now be located within ActorState objects.  In the
1809
past, InitiateTopics were only found when they were directly within an
1810
Actor or a TopicGroup within an actor.  The library now looks for
1811
InitiateTopics in the current actor state object as well, which is
1812
more consistent with other topic types.
1813
1814
</div>
1815
1816
<!------------------->
1817
<div class=entry>
1818
1819
inputManager.pauseForMore() now re-activates the transcript if it was
1820
active before the pause.  In the past, this function simply flushed
1821
output and left the transcript deactivated.  This was problematic for
1822
certain library subsystems that depend upon the transcript being
1823
active throughout a command.  Now, the function flushes the
1824
transcript's pending output up to the pause, then reactivates the
1825
transcript after the pause, so that transcript capture proceeds as
1826
normal throughout the rest of the command.
1827
1828
</div>
1829
1830
<!------------------->
1831
<div class=entry>
1832
1833
In the past, the library generally assumed that NestedRoom objects
1834
would only be located inside either Rooms or other NestedRooms, but
1835
never inside ordinary Things.  However, in practice it's often useful
1836
to be able to put a nested room inside something that's not itself
1837
a nested room.
1838
1839
<p>A number of small library changes should now make NestedRooms
1840
work properly when located inside ordinary Thing objects.  The
1841
changes are mostly internal and should have no impact on existing
1842
code, but for reference, here's what's changed:
1843
1844
<ul>
1845
1846
<li>The methods getRoomPartLocation(), getLocTraveler(),
1847
atmosphereList(), roomDaemon(), getDropDestination(), and
1848
effectiveFollowLocation() have been moved to Thing, with essentially
1849
no changes.  These are the methods the library calls on containers of
1850
nested rooms, so moving them to Thing allows any game object to
1851
contain a nested room.
1852
1853
<li>The definitions of most of the above methods have been removed
1854
from BasicLocation, since BasicLocation now simply inherits the Thing
1855
definitions.  The definitions of roomDaemon() and atmosphereList()
1856
have been moved to Room instead, since those definitions were intended
1857
for top-level rooms.
1858
1859
<li>Room now defines checkActorOutOfNested() to find and defer to
1860
the child object containing the actor.  This ensures that the check
1861
is forwarded to the nested room containing the actor.
1862
1863
</ul>
1864
1865
<p>In addition to the changes above, NestedRoom no longer assumes that
1866
its immediate location is the destination when an actor within the
1867
nested room leaves the nested room.  Instead, NestedRoom now
1868
consistently uses the value given by exitDestination.  Further,
1869
NestedRoom.exitDestination itself no longer uses the immediate
1870
container as its default setting, but instead uses the default staging
1871
location as given by the defaultStagingLocation method.
1872
1873
</div>
1874
1875
<!------------------->
1876
<div class=entry>
1877
1878
A change in 3.0.10 introduced a parsing problem with distinguishing
1879
nouns from plurals when the words were right at the parser's
1880
truncation length.  To be more precise, if you defined a noun that was
1881
exactly the truncation length, <i>and</i> you also defined a plural
1882
for that noun as the noun plus "s" (or, actually, as the noun plus any
1883
other letters), then the parser would incorrectly interpret the noun
1884
word in player input as though it were plural.
1885
1886
<p>For example, the default truncation length is 6 characters, so this
1887
problem occurred with "button" and "buttons" defined as a noun and
1888
plural, respectively.  In this case, if you had two or more objects in
1889
scope with vocabulary like 'red button*buttons', and the player typed
1890
something like "x button", the parser incorrectly treated the "button"
1891
in the player's input as though it were plural, so it applied the
1892
Examine command iteratively to all of the buttons in scope, rather
1893
than asking the player which singular button they intended to examine.
1894
1895
<p>This problem has now been corrected.
1896
1897
</div>
1898
1899
<!------------------->
1900
<div class=entry>
1901
1902
The message definition for cannotSetToMsg was missing from the English
1903
message list (in en_us/msg_neu.t).  The message is now there.
1904
1905
</div>
1906
1907
<!------------------->
1908
<div class=entry>
1909
1910
A command of the form PUSH <i>pushable</i> INTO <i>object</i>, where
1911
the second object was some random, non-enterable thing, yielded an
1912
unformatted message ("{that/he dobj} {is} not something you can
1913
enter").  The underlying problem was that the action remapping invoked
1914
by PushTravelViaIobjAction didn't properly set up the object
1915
parameters for the remapped verb, leaving the message system unable to
1916
find the direct object.  This has been corrected.
1917
1918
</div>
1919
1920
<!------------------->
1921
<div class=entry>
1922
1923
The Attachable class had a problem that caused a run-time error when
1924
the player entered a command of the form DETACH <i>object</i>, where
1925
<i>object</i> was an Attachable and the command had no indirect
1926
object.  The problem came from a name conflict between an Attachable
1927
method called cannotDetachMsg(obj), which took one parameter, and a
1928
library messages property of the same name, which takes no parameters.
1929
When the message resolution system tried to retrieve the library
1930
message from the direct object, it invoked the zero-parameter version
1931
of the property, which caused the run-time error due to the parameter
1932
mismatch with the one-parameter version implemented in Attachable.
1933
1934
<p>To fix this problem, the method in Attachable has been renamed to
1935
cannotDetachMsgFor(obj).  The library message has the same name as
1936
before.
1937
1938
<p>Any existing code that overrode the Attachable method will have to
1939
adjust for the name change.  That said, it seems almost impossible for
1940
this change to affect existing code, since the very bug that we're
1941
talking about here would have prevented the override from working
1942
properly in the first place.
1943
1944
</div>
1945
1946
<!------------------->
1947
<div class=entry>
1948
1949
A library bug caused a run-time error ("stack overflow") on commands
1950
like REMOVE ME or REMOVE <i>nested room containing me</i>.  This has
1951
been corrected.
1952
1953
<p>(The specific problem is as follows.  The library assumes that a
1954
REMOVE X command will result in the actor taking X, and so as a sanity
1955
check calculates how much weight the actor would be holding if that
1956
were allowed.  When X is the actor or contains the actor, the
1957
hypothetical weight check created a circular containment situation;
1958
the stack overflow came from the library's attempt to recursively
1959
visit all of the hypothetical contents of the actor, which is of
1960
course an infinite loop in a circular containment situation.  To avoid
1961
this problem, the library now ignores hypotheticals that would create
1962
circular containment.  It's safe to ignore these hypothetical tests
1963
because commands that perform them should always be disallowed anyway,
1964
since actual circular containment is never allowed.)
1965
1966
</div>
1967
1968
<!------------------->
1969
<div class=entry>
1970
1971
A library bug caused a run-time error ("nil object reference") on
1972
entering a command of the form <i>object</i>, <i>unknown word</i>,
1973
where <i>object</i> was any in-scope non-Actor object.  This has
1974
been corrected.
1975
1976
<p>(The problem came about because the parser attempted to treat such
1977
a command as though it were directed to an NPC.  This is some special
1978
handling that applies when the command has a syntax error; the point
1979
is to let the author customize the parsing error messages for orders
1980
given to particular actors.  However, when <i>object</i> isn't an
1981
actor, this is problematic, because the library assumes that it can
1982
call certain Actor methods on the object in question.  The fix is that
1983
the library will only apply this handling in cases where the object is
1984
actually an Actor; in other cases, it won't assume that the command
1985
was intended as an order to an NPC, so it will simply use the default
1986
parsing error messages.)
1987
1988
</div>
1989
1990
1991
<!------------------------------- 3.0.12 --------------------------------->
1992
<div class="sepbar"><a name='3012'></a>3.0.12</div>
1993
<p><b><i>TADS 3.0 General Release version - Released 9/15/2006</i></b>
1994
<p>
1995
1996
<!------------------->
1997
<div class=firstentry>
1998
1999
The library didn't properly handle situations where an NPC order
2000
involved multiple objects and a failed implied sub-action.  If an
2001
implied action failed for one of the objects involved, the implied
2002
action was assumed to have failed for all <i>subsequent</i>
2003
objects in the multiple object list as well, even if the subsequent
2004
implied actions actually succeeded.  This resulted in self-contradictory
2005
transcripts, where an implied action was reported as successful, but
2006
then was followed by a message that the implied action had failed:
2007
2008
<p><pre>
2009
  Bob takes the coin.
2010
  Bob must be holding the coin first.
2011
</pre>
2012
2013
<p>The problem was that the implied action mechanism was incorrectly
2014
considering the failure status for the entire top-level command when
2015
determining if the subsequent implied actions failed.  Instead, it
2016
should have been checking the status of the implied actions
2017
themselves.  It now does this by looking for a failure report within
2018
the implied action's reports, rather than looking for a failure
2019
anywhere within the entire transcript.
2020
2021
</div>
2022
2023
<!------------------->
2024
<div class=entry>
2025
2026
SpaceOverlay.getWeight() now omits the object's "contents" from the
2027
weight calculation if the contents are to be abandoned when the object
2028
is moved.  If the contents are to be abandoned, it means that they're
2029
not actually attached to or contained within the space overlay, but
2030
are simply colocated with it; they thus have no contribution to the
2031
overlay's total weight.  If the contents are <i>not</i> to be
2032
abandoned on moving the overlay object, they're effectively attached
2033
to it, so they do contribute to its weight as normal.
2034
2035
</div>
2036
2037
<!------------------->
2038
<div class=entry>
2039
2040
CaptureFilter is now a subclass of OutputFilter (it was formerly just
2041
an 'object'); and SwitchableCaptureFilter is a subclass of
2042
CaptureFilter (it also was just an 'object').  This should make no
2043
difference functionally, as an output filter is only required to
2044
implement the filterText() method, but is desirable anyway in that it
2045
makes an ofKind(OutputFilter) test recognize these object types as
2046
output filter subclasses.
2047
2048
</div>
2049
2050
2051
<!------------------------------- 3.0.11 --------------------------------->
2052
<div class="sepbar"><a name='3011'></a>3.0.11</div>
2053
<p><b><i>Released 9/8/2006</i></b>
2054
<p>
2055
2056
<div class=firstentry>
2057
2058
<i>Very</i> slight compatibility risk: NameAsOther (and thus
2059
NameAsParent) no longer maps the "in" names to its target object.  The
2060
"in" names are the names generated when an object is described as
2061
contained within the NameAsOther.  In the past, these were mapped to
2062
the target object along with all of the ordinary names for the object.
2063
However, this was the wrong behavior for ComplexComponent, which
2064
inherits from NameAsOther, because the containment relationship
2065
between a ComplexContainer and its contents is defined by the
2066
container subclass mixed with ComplexComponent in the object's
2067
superclass list, <i>not</i> by the target object, which in this case
2068
is the ComplexContainer of which the ComplexComponent is a part.
2069
2070
<p>Although it's conceivable that some other applications of
2071
NameAsOther would actually want the old behavior, it seems highly
2072
unlikely, so we don't expect any practical compatibility list.
2073
2074
<p>However, we have provided a new mix-in class, ChildNameAsOther,
2075
that adds mappings for all of the "in" names to the target object.
2076
So, if you have a NameAsOther that depends upon the old "in" name
2077
mapping, just add ChildNameAsOther to the object's superclass list
2078
(right after NameAsOther or NameAsParent), and you'll get the same
2079
behavior as before.
2080
2081
</div>
2082
2083
<!------------------->
2084
<div class=entry>
2085
2086
In 3.0.10, the ImpByeTopic was differentiated into a couple of
2087
subclasses to allow handling implicit goodbyes differently when
2088
desired (see <a href='#ImpByeTopicSubclasses'>below</a>).  However,
2089
this change didn't handle one type of goodbye correctly, namely the
2090
NPC-initiated goodbye, via npc.endConversation().  The change
2091
incorrectly made it so that those goodbyes were treated the same as
2092
explicit <i>player</i>-initiated goodbyes.
2093
2094
<p>Prior to the 3.0.10 change, NPC-initiated goodbyes were subsumed
2095
into the undifferentiated "implicit goodbye" category, and they
2096
should clearly remain in that category; they simply need to be
2097
differentiated like the other implicit goodbyes were in the 3.0.10
2098
change.
2099
2100
<p>To this end, the new topic class ActorByeTopic has been added; this
2101
is analogous to BoredByeTopic and LeaveByeTopic, and is used when the
2102
NPC terminated the conversation via npc.endConversation().  In the
2103
absence of an active ActorByeTopic, the active ImpByeTopic will be
2104
used instead.  This restores compatibility with pre-3.0.10 code (where
2105
there was no differentiation among "implied goodbye" types, and
2106
npc.endConversation() events were handled as implied goodbyes), while
2107
providing a specific topic type to handle this one type of goodbyes.
2108
2109
</div>
2110
2111
<!------------------->
2112
<div class=entry>
2113
2114
The English library's "instructions" module (instruct.t) now uses HTML
2115
markups to display typographical quotes and apostrophes ("curly
2116
quotes") throughout the text of the standard instructions.  Thanks to
2117
Greg Boettcher for making this improvement.
2118
2119
</div>
2120
2121
<!------------------->
2122
<div class=entry>
2123
2124
The detailed-naming scheme for object announcements (see <a
2125
href='#getInScopeDistinguisher'>below</a>) introduced in 3.0.10 has
2126
been made optional, and disabled by default.  Testing reveals that the
2127
mechanism as currently designed is too twitchy for some people's
2128
taste, so we've disabled it by default for the time being; however,
2129
the code is all intact, for those who want to use it as-is or tweak it
2130
for their needs.  To enable the detailed announcement naming, set
2131
gameMain.useDistinguishersInAnnouncements to true.
2132
2133
</div>
2134
2135
<!------------------->
2136
<div class=entry>
2137
2138
The BannerWindow system had a flaw in the way it re-initialized
2139
banners after a RESTART.  The problem showed up in cases where there
2140
were dependency orderings among the windows, so that one window's
2141
initBannerWindow() had to call another's initBannerWindow() in order
2142
to create the windows in the correct order.  The problem didn't always
2143
happen even in cases of ordering dependencies, since it also depended
2144
on the arbitrary ordering of the VM's internal object lists.  When it
2145
happened, the problem manifested itself by creating extra copies of an
2146
affected banner window at each RESTART.  This has now been corrected.
2147
2148
</div>
2149
2150
<!------------------->
2151
<div class=entry>
2152
2153
In banner.t, the formerly anonymous InitObject that handles banner
2154
initialization (and post-RESTART re-initialization) now has a name,
2155
bannerInit.  This is so that games can use "modify" and "replace" with
2156
the object, and also so they can refer to it from the execBeforeMe
2157
properties of other InitObjects, for initialization dependency
2158
ordering purposes.
2159
2160
</div>
2161
2162
<!------------------->
2163
<div class=entry>
2164
2165
"Follow mode" for NPCs ("Bob, follow me") didn't work correctly when
2166
the actor being followed moved between two top-level rooms connected
2167
by a sight sense connector.  This has been corrected.  (The problem
2168
was that the code that carried out the "follow" attempted to move the
2169
follower using a "local travel" action - something like STAND ON STAGE
2170
or ENTER BOOTH - any time the target actor was still in sight.  The
2171
follower now attempts local travel only if the target is still in
2172
sight <i>and</i> the target is within the same top-level room;
2173
otherwise, the follow uses a suitable full-fledged travel action.)
2174
2175
</div>
2176
2177
<!------------------->
2178
<div class=entry>
2179
2180
In Actor.actorActionFollow(), if the actor is already in "follow" mode
2181
for the requested other actor, a message is now displayed to this
2182
effect (alreadyFollowModeMsg: "I'm already following Bob").  This
2183
won't be a factor by default, since the library automatically cancels
2184
"follow" mode any time a new command is issued to an actor
2185
<i>before</i> attempting to enact the new command.  However, games
2186
might want to override this auto-cancel behavior, in which case they
2187
might encounter this situation in actorActionFollow().  In the past,
2188
the routine did nothing at all - it didn't even show a message, so the
2189
generally undesirable "Nothing happens" was displayed by default.
2190
2191
</div>
2192
2193
<!------------------->
2194
<div class=entry>
2195
2196
In the past, an actor that started in an InConversationState triggered
2197
a run-time error at start-up, due to an initialization order problem
2198
in the library.  This has been corrected.  (In particular, an actor's
2199
boredAgendaItem property is now initialized via a perInstance()
2200
definition rather than in initializeActor().  This ensures that the
2201
property is initialized before it's needed.  In the past, the order of
2202
initializations sometimes resulted in the library trying to use the
2203
actor's BoredAgendaItem object before it was initialized, leading to a
2204
"nil object reference" error.)
2205
2206
</div>
2207
2208
<!------------------->
2209
<div class=entry>
2210
2211
Room's condition for remapping the GetOutOf action to the Out action
2212
has changed slightly.  In the past, this remapping was performed only
2213
if the 'out' direction had an <i>apparent destination</i>, which is
2214
only the case when the actor attempting the travel already knows the
2215
destination (such as from past experience or at-hand information).
2216
This condition wasn't quite right, though.  Instead, the condition
2217
should have been simply that the 'out' direction has an apparent
2218
<i>connector</i> - that is, there's a visible way to travel in the
2219
'out' direction.  Room has been changed to use the new condition.
2220
2221
</div>
2222
2223
<!------------------->
2224
<div class=entry>
2225
2226
The template (in en_us/en_us.h) for DeadEndConnector now makes the
2227
apprentDestName entry optional.  This allows using the template to
2228
define a dead-end connector that merely displays a message when
2229
traversed, without giving it a name.
2230
2231
</div>
2232
2233
<!------------------->
2234
<div class=entry>
2235
2236
In the English library, PathPassage now limits its remapping of the
2237
Take action to the TravelVia action to cases where the entered verb
2238
phrase was literally "take."  This prevents other phrasings, such as
2239
"pick up path" or "get path," from being interpreted as attempts to
2240
travel along a path.
2241
2242
</div>
2243
2244
<!------------------->
2245
<div class=entry>
2246
2247
The message sayTravelingRemotely in the English library has been
2248
corrected to add the word "to" before the destination name.
2249
2250
</div>
2251
2252
2253
<!------------------------------- 3.0.10 --------------------------------->
2254
<div class="sepbar"><a name='3010'></a>3.0.10</div>
2255
<p><b><i>Released 8/17/2006</i></b>
2256
<p>
2257
2258
<div class=firstentry>
2259
2260
<b>Incompatibility warning:</b> <i>(This note concerns a change that
2261
was made in 3.0.9 but inadvertantly omitted from the 3.0.9 release
2262
notes.  We're mentioning it now in case anyone was affected by it
2263
and needs help adjusting their code for the change.)</i>
2264
2265
<p>In version 3.0.9, gameMain.verboseMode was changed from a simple
2266
true/nil property to an object of class BinarySettingsItem.  Any
2267
existing game code that attempted to turn verbose mode on or off by
2268
setting gameMain.verboseMode to true or nil will now encounter a run-time
2269
error the first time the player enters a travel command.
2270
2271
<p>If you want to set the default verbosity mode explicitly in your
2272
game, you can't do it any more by setting gameMain.verboseMode to true
2273
or nil.  Instead, you can add a line like this to a start-up routine,
2274
such as gameMain.newGame():
2275
2276
<p>
2277
<pre>
2278
   gameMain.verboseMode.isOn = true; // turn on verbose mode
2279
</pre>
2280
2281
<p>Note that the verbosity mode is now part of the "global
2282
preferences" mechanism, so in most cases it's best for games not to
2283
change it explicitly, instead leaving it up to the player to decide on
2284
the setting.  In the past, some authors liked to set a verbosity mode
2285
that they felt was most suitable for the game.  Now that the player
2286
can specify a set of default preferences that they wish to apply to
2287
all games, it's better for authors not to presume to change the
2288
player's default settings without a good reason.  As with any other
2289
rule, there are bound to be exceptions, so if you have a really good
2290
reason to override the player's preferences then you should feel free
2291
to do so.  But if you're tempted to override the player's preferences
2292
just because <i>you</i> like it a particular way, you might want to
2293
reconsider.
2294
2295
</div>
2296
2297
<!------------------->
2298
<div class=entry>
2299
2300
Minor incompatibility warning: The Lockable class now has
2301
initiallyLocked set to true.  This means that <i>all</i> Lockable
2302
objects now start out locked by default (i.e., unless your game code
2303
specifically overrides initiallyLocked to set it to nil for a given
2304
Lockable).  In the past, Lockable didn't define initiallyLocked at all
2305
(so it defaulted to nil), but Door and IndirectLockable defined it as
2306
true - so some Lockables formerly started out locked by default while
2307
others were unlocked by default.  This change should be generally
2308
beneficial, since (1) it simplifies matters by making the initial lock
2309
status consistent across all Lockables, and (2) the vast majority of
2310
Lockables start out locked anyway, so "locked" is the better default.
2311
2312
<p>If you have any Lockables in existing code that you specifically
2313
intended to start out unlocked, and you didn't explicitly set
2314
initiallyLocked to nil in those objects, you'll have to do so now.
2315
2316
</div>
2317
2318
<!------------------->
2319
<div class=entry>
2320
2321
Minor incompatibility warning: The method Action.callVerifyPrecond has
2322
been renamed to callVerifyPreCond - that is, the 'c' in 'precond' is
2323
now capitalized.  This change is for better naming consistency, since
2324
all of the other symbol names in the library that include the
2325
substring "precond" capitalize the C.  This routine is intended mostly
2326
for internal use within the library, so it should affect little or no
2327
existing game code.
2328
2329
</div>
2330
2331
<!------------------->
2332
<div class=entry>
2333
2334
Minor incompatibility warning: The NOTE command has been removed, and
2335
replaced by a new comment syntax that lets the player enter a comment
2336
by starting a command line with a punctuation-mark prefix.
2337
2338
<p>The default comment prefix is now an asterisk ("*").  You can
2339
change this to any prefix string you'd like by modifying the
2340
commentPrefix property of the commentPreParser object.  You can also
2341
control whether or not leading whitespace is allowed before the
2342
comment prefix (it is by default) by modifying commentPreParser's
2343
leadPat property.
2344
2345
<p>Using NOTE as the comment prefix was problematic because NOTE is a
2346
common enough word that games often want to use it in an object's
2347
name, and this creates situations where a user might want to start an
2348
input line with NOTE with the intention of referring to an object, not
2349
of entering a comment.  It was essentially impossible in some of these
2350
cases to reliably determine which the player meant.  The new approach
2351
avoids these problems by using syntax that should be unambiguous in
2352
nearly all games.
2353
2354
<p>In the past, there was a StringPreParser object in the English
2355
library that helped the NOTE command by quoting the note text in some
2356
cases.  This preparser has been removed, and a new preparser has been
2357
added in its place, but this time in the general library, in misc.t.
2358
The new object is called commentPreParser, and it performs all of the
2359
comment handling itself, without the need for a separate NOTE action.
2360
2361
<p>As part of this change, NoteAction and NoteIAction have been
2362
eliminated.  In the unlikely event that you used 'modify' to change
2363
the behavior of these actions, you'll have to rework your code.  Look
2364
at the commentPreParser object for details of the new arrangement.
2365
2366
</div>
2367
2368
<!------------------->
2369
<div class=entry>
2370
2371
Minor incompatibility warning: Each actor now has its own separate
2372
lookup table of ConvNode names.  This means that you don't have to
2373
worry about making ConvNode names unique globally - you only have to
2374
make sure that names are unique within a single actor's set of nodes.
2375
2376
<p>This shouldn't affect existing game code, except for cases where
2377
you refer directly to conversationManager.convNodeTab.  You should
2378
scan your source for occurrences of "convNodeTab" and change any that
2379
you find to "actor.convNodeTab", where "actor" is the Actor who owns
2380
the table.  The most likely place for game code to refer to
2381
convNodeTab is in a "modify conversationManager" definition.
2382
2383
</div>
2384
2385
<!------------------->
2386
<div class=entry>
2387
2388
Minor incompatibility warning: Thing.getExtraScopeItems() is now
2389
required to return a list - nil is no longer a valid return value
2390
for this method.  Use an empty list instead of nil to indicate that
2391
there's nothing to add to the current scope.  The old nil return
2392
code was inconsistent and unnecessary, as an empty list always
2393
functionally meant the same thing anyway.
2394
2395
<p>It's very unlikely that this change will affect any existing
2396
game code, since any game code that overrides this method almost
2397
certainly did so to add something to the scope.  However, you
2398
do a quick search through your game code for getExtraScopeItems(),
2399
and make sure that you don't have any nil returns; if you do,
2400
simply change them to empty lists ("return [];").
2401
2402
</div>
2403
2404
<!------------------->
2405
<div class=entry>
2406
2407
Minor incompatibility warning: Thing.getListedContentsInExamine() has
2408
been renamed to getContentsForExamine(), and its operation changed
2409
slightly.  The old name was a bit misleading, in that the method
2410
actually needs to return all of the visible contents of the object,
2411
whether or not they're marked as listable.  Unlistable contents need
2412
to be included in this list so that their listable contents can be
2413
included recursively.  This is the operational change: in the past,
2414
only listable contents were included in the returned list; now, all
2415
visible contents are included.
2416
2417
<p>This change corrects an inconsistency that occurred in cases where
2418
an object had fixed-in-place contents that themselves had contents.
2419
In the past, directly examining such an object didn't mention anything
2420
about the contents of the second-level containers, while a simple LOOK
2421
<i>did</i> include the inner contents.  The change makes the two cases
2422
consistent.
2423
2424
<p>This change should have little or no effect on existing code, since
2425
the former getListedContentsInExamine() method is an internal method
2426
that's unlikely to have been called or overridden in game code.  If
2427
you overrode this routine, though, you'll need to apply the name
2428
change to your code, and make any adjustments for the slight change in
2429
the method's semantics.
2430
2431
</div>
2432
2433
<!------------------->
2434
<div class=entry>
2435
2436
Minor incompatibility warning: the "equivalent object" mechanism has
2437
changed substantially, although existing game code shouldn't be
2438
affected unless it was modifying the equivalence mechanism itself.
2439
2440
<p>In the past, equivalence was based on the superclass of the object.
2441
Two objects were equivalent if (a) they both had isEquivalent set to
2442
true, and (b) they had identical superclass lists.  This approach to
2443
equivalence was occasionally problematic, particularly when using
2444
"proxy" objects to modify the behavior of objects involved in
2445
equivalence groups.  In addition, the superclass approach was somewhat
2446
counterintuitive: the whole point of the equivalence mechanism is to
2447
treat objects with identical names as interchangeable, but using
2448
superclasses as the basis of the equivalence had nothing to do with
2449
the naming.
2450
2451
<p>The new scheme is based on a new property called equivalenceKey,
2452
which is defined in the language module.  In the English library, the
2453
default setting of this new property is the disambigName of the
2454
object.  So, equivalence groups are now simply based on the basic
2455
disambiguation name of the object.  This is much more consistent with
2456
the disambiguation mechanism itself, because it means that the parser
2457
decides whether objects are interchangeable using essentially the same
2458
logic that the player uses intuitively: if the game always refers to
2459
two objects by the same name, they're interchangeable.
2460
2461
<p>Another advantage of the new scheme is that it's much more
2462
customizable than the old scheme.  Since the basis of the equivalence
2463
decision is now distinguished as a separate property (equivalenceKey),
2464
you can control equivalence groups simply by overriding the property.
2465
You could even effectively restore the old scheme by defining
2466
equivalenceKey as getSuperclassList() - this would make the immediate
2467
superclass list of an object the basis of its equivalence grouping,
2468
producing the same behavior as in the past.
2469
2470
<p>Note that if you change an object's equivalenceKey dynamically
2471
during play - or if you change its underlying disambigName property -
2472
the object's listing group <b>won't</b> be automatically updated.  If
2473
you do make such a change and you want to update the object's listing
2474
group, just call initializeEquivalent() on the object.  (Under the old
2475
scheme, there was really no way to change an object's grouping - even
2476
if you changed its name, it was still grouped based on its class,
2477
which could have caused strange results in listings.  The new scheme
2478
at least allows for this kind of change, although it requires this
2479
manual step to keep the list grouping settings in sync.)
2480
2481
</div>
2482
2483
<!------------------->
2484
<div class=entry>
2485
2486
In the past, when EXAMINE was applied to a Room, the Room simply
2487
turned the command into a nested LOOK AROUND command.  This has
2488
changed slightly.  Now, the Room directly does the work that LOOK
2489
AROUND would do, without the nested command, and with the difference
2490
that the initial line with the room name in boldface isn't included in
2491
the output.  (This is accomplished by omitting the LookRoomName flag
2492
from the 'verbose' flags for the Actor.lookAround() call.)
2493
2494
<p>There are two reasons for this change.  First, when the player
2495
explicitly types EXAMINE <i>room name</i>, it's somewhat redundant to
2496
include the room name in the output.  Second, when the player types
2497
EXAMINE ALL or EXAMINE <i>list of things</i>, the standard
2498
multi-object-command output format already prefaces the results for
2499
each item in the list with the name of the item ("kitchen:"), which
2500
made the room name line especially redundant in this case.
2501
2502
</div>
2503
2504
<!------------------->
2505
<div class=entry>
2506
2507
An object can now be associated with more than one CollectiveGroup.
2508
This allows an object to be a member of multiple disjoint groups.
2509
For example, you could create a group for "treasure," and a group
2510
for "jewelry," and put some objects in both groups, while leaving
2511
others in one group or the other.
2512
2513
<p>To define multiple CollectiveGroups for a given object, use the new
2514
property 'collectiveGroups' on the objects that you want to associate
2515
with the groups.  Set this property to a list with the CollectiveGroup
2516
objects to associate with the given object.
2517
2518
<p>You can still use the single-valued 'collectiveGroup' property, so
2519
existing game code will continue to work unchanged.  However,
2520
'collectiveGroup' is now obsolescent, so you should not use it for new
2521
code - use 'collectiveGroups' instead.  For compatibility with
2522
existing code, the library's default definition of
2523
Thing.collectiveGroups is a method that returns an empty list if
2524
collectiveGroup is nil, or a one-element list containing the
2525
collectiveGroup value if the value is not nil.  Since this is slightly
2526
ineffecient, support for the old 'collectiveGroup' will probably
2527
eventually be removed, at which point the default for
2528
'collectiveGroups' will simply be an empty list.
2529
2530
</div>
2531
2532
<!------------------->
2533
<div class=entry>
2534
2535
Several new classes bring functionality parallel to
2536
RestrictedContainer to surfaces, undersides, and rear containers and
2537
surfaces.  The new classes are RestrictedSurface, RestrictedUnderside,
2538
RestrictedRearContainer, and RestrictedRearSurface.  These new classes
2539
(along with RestrictedContainer itself) are all based on the new
2540
mix-in class RestrictedHolder, which defines generic containment
2541
restriction rules that can be applied to any container subtype.
2542
2543
<p>The new classes work just like RestrictedContainer did, and
2544
RestrictedContainer itself hasn't changed its behavior (it's been
2545
refactored slightly for the new base class, but this is just an
2546
internal change that shouldn't affect any existing code).  To
2547
accommodate the new types of restriction, suitable new library "player
2548
action" messages have been added (cannotPutOnRestrictedMsg,
2549
cannotPutUnderRestrictedMsg, cannotPutBehindRestrictedMsg).
2550
2551
</div>
2552
2553
<!------------------->
2554
<div class=entry>
2555
2556
In the past, the default Search action handling was the same as for
2557
LookIn.  Now, the Search handling is slightly different for Container
2558
and Openable.
2559
2560
<p>First, Openable adds an objOpen precondition for Search if the
2561
actor isn't inside the object; for LookIn, this is skipped if the
2562
object is transparent.
2563
2564
<p>Second, in the Search check() method, Container requires that the
2565
object be openable or transparent to the "touch" sense, or that the
2566
actor is inside the container.  LookIn is similar, but only requires
2567
that the container to be non-opaque in the <b>"sight"</b> sense.
2568
2569
<p>The reason for these changes is that Search implies a more thorough,
2570
physical examination than LookIn does.  To most people, an explicit
2571
search involves physically poking through an object's contents, while
2572
"look in" is more passive, implying just having a look inside.
2573
2574
</div>
2575
2576
<!------------------->
2577
<div class=entry>
2578
2579
In the past, the Thing handlers for PUT UNDER and PUT BEHIND included
2580
touchObj preconditions on the direct object instead of objHeld
2581
preconditions.  These have been changed to objHeld conditions; since
2582
these verbs generally require physically moving the direct object, the
2583
correct precondition is that the direct object be held, just as for
2584
the other PUT verbs.
2585
2586
</div>
2587
2588
<!------------------->
2589
<div class=entry>
2590
2591
A new Action method, getEnteredVerbPhrase(), returns the action's
2592
original verb phrase text as typed by the player.  The return value is
2593
a string giving the verb phrase in a canonical format: specifically,
2594
the result is all in lower-case, and each noun phrase in the player's
2595
input is replaced by a placeholder token: '(dobj)' for the direct
2596
object, '(iobj)' for the indirect object, '(topic)' for a topic
2597
phrase, and '(literal)' for a literal text phrase.  Only the verb
2598
phrase is included in the result - there's no target actor phrase, and
2599
no sentence-ending punctuation included.  The noun phrase replacements
2600
apply to the <i>entire</i> noun phrases, so the single placeholder
2601
'(dobj)' could represent an entire list of direct objects.  For
2602
example, if the player types "BOB, PUT THE BOOK AND PENCIL IN THE BOX
2603
AND GIVE IT TO ME", calling getEnteredVerbPhrase() on the PutIn action
2604
would yield 'put (dobj) in (iobj)', and calling the method on the
2605
GiveTo would yield 'give (dobj) to (iobj)'.
2606
2607
<p>There are two reasons why the method returns the canonical format
2608
rather than the full text of the entire command.  First, the full text
2609
is already readily available, via gAction.getOrigText(), so there's no
2610
need for a new method to retrieve this information.  Second, and more
2611
importantly, the canonical format isoaltes the verb phrase structure
2612
of the player's input, independently of any noun phrases, making it
2613
easy to determine exactly which verb phrasing the player actually used.
2614
2615
<p>This method is most useful in cases where the library's verb rules
2616
define two or more different phrasings for the same Action, and you
2617
need to be able to distinguish exactly which variant the player
2618
entered.  For the most part, this is unnecessary: when the library's
2619
verb rules include synonyms, it's because the different phrasings
2620
usually have exactly the same abstract meaning, hence it's enough to
2621
know which Action matched the grammar.  In some cases, though, a
2622
particular verb applied to a particular object has an idiomatic
2623
meaning different from the usual meaning for other objects, and in
2624
those cases the generic synonyms often fail to be idiomatic synonyms.
2625
2626
<p>For example, the library defines "get (dobj)" and "take (dobj)" as
2627
synonyms for the Take action, because GET and TAKE can almost always
2628
be used interchangeably.  However, if you were defining an "aspirin"
2629
object, you might want to treat the command "take aspirin" as meaning
2630
"eat aspirin," but you would still want "get aspirin" to mean "pick up
2631
aspirin."  You could handle this by overriding the dobjFor(Take)
2632
action() method on the aspirin object, comparing
2633
gAction.getEnteredVerbPhrase() to 'take (dobj)', and calling
2634
replaceAction(Eat, self) if it's a match.
2635
2636
</div>
2637
2638
<!------------------->
2639
<div class=entry>
2640
2641
The new Action method getPredicate() returns the verb phrase match
2642
tree object that the parser resolved to the Action.  The English
2643
library uses Action objects as predicate match tree objects, so in the
2644
English version this simply yields the original Action.  However,
2645
non-English libraries can use separate objects for verb phrase match
2646
tree objects, so if you need any information from the verb phrase's
2647
grammar tree (for example, if you need to call getOrigText() or
2648
getOrigTokenList()), you should use action.getPredicate() rather than
2649
using the action object directly.  (This does <b>not</b> apply to the
2650
new method getEnteredVerbPhrase() above - that method is explicitly
2651
defined on the Action, not the grammar object.  getEnteredVerbPhrase()
2652
itself calls getPredicate() to get the grammar information, so you can
2653
simply call getEnteredVerbPhrase() directly on the Action object.)
2654
2655
</div>
2656
2657
<!------------------->
2658
<div class=entry>
2659
2660
The library looks to a new global variable, gLibMessages, to determine
2661
which object to use as the "library message" source.  (This is the
2662
object used for messages that don't logically relate to the current
2663
actor; generally, these messages are replies to meta-commands, or text
2664
fragments used to construct descriptions.)
2665
2666
<p>In the past, the library simply used the libMessages object
2667
directly as the source of these messages.  Now, the library instead
2668
uses the current value of gLibMessages as the message source.  The
2669
default value of gLibMessages is libMessages, and the library never
2670
changes this value itself, so the default behavior is exactly the same
2671
as before.
2672
2673
<p>The purpose of this change is to allow a game to switch to a new
2674
set of library messages dynamically during play.  For example, if your
2675
game is structured into chapters with different points of view, you
2676
might want to use a distinctive writing styles for the different
2677
chapters, in which case you'd want to change all of the library
2678
messages at each chapter transition.  To do this, simply set
2679
gLibMessages to refer to a new object at each point when you want to
2680
switch message sources; subsequent messages will come from your new
2681
source object.  Note that it's not necessary to do this if you only
2682
want to customize messages statically (i.e., throughout the entire
2683
game); for that, you can just 'modify libMessages'.
2684
2685
</div>
2686
2687
<!------------------->
2688
<div class=entry>
2689
2690
In the past, the Floor class replied to THROW <i>object</i> AT FLOOR
2691
with the same default message ("you should just put it down instead")
2692
in all cases.  This reply is no longer used in cases where the Floor
2693
is unreachable; instead, the standard THROW handling applies, since
2694
the player couldn't accomplish the same thing with DROP.
2695
2696
</div>
2697
2698
<!------------------->
2699
<div class=entry>
2700
2701
RoomPart.getHitFallDestination() will now take into account any
2702
explicit 'location' setting in the RoomPart when determining the
2703
destination.  In the past, an explicit 'location' setting was ignored,
2704
and a valid destination could only be found if the RoomPart was in the
2705
same top-level room as the actor.  Now, if the RoomPart has an
2706
explicit non-nil location setting, that takes precedence in
2707
determining the destination.  This is useful when creating connected
2708
top-level locations with room parts that you want capable of serving
2709
as THROW targets.
2710
2711
</div>
2712
2713
<!------------------->
2714
<div class=entry>
2715
2716
When throwing an object at a target, and the target happens also to be
2717
the place where the object is described as landing when thrown at that
2718
target (i.e., the target is the nominal drop destination of its own
2719
the "hit-fall" destination), a new default message is used, of the
2720
form "The projectile lands on the target."  In the past, the message
2721
was the awkward "The projectile hits the target without any obvious
2722
effect, and falls to the target."  This was most likely to occur when
2723
the target was something like a floor or ground object, since that's
2724
the only case where the target is likely to also be the nominal drop
2725
destination.  This change is in the routine
2726
DropTypeThrow.standardReport().
2727
2728
</div>
2729
2730
<!------------------->
2731
<div class=entry>
2732
2733
GIVE TO, SHOW TO, and THROW TO now use different messages depending on
2734
whether the indirect object is an actor or an inanimate object.  For
2735
ordinary Things, the message is now of the form "You can't give
2736
anything to X"; for Actors, the message is "The X does not appear
2737
interested."  In the past, the latter message was used for all
2738
objects, animate or not.  Imputing "interest" to an inanimate object
2739
could be read as either intentionally snide (as though the library
2740
were sarcastically calling the player dense for trying such an
2741
obviously stupid thing) or simply wrong (as though the library didn't
2742
know the difference); since msg_neu is supposed to affect a neutral
2743
narrative tone, neither alternative is desirable.
2744
2745
<p>In addition, showing or giving an Actor to itself is now handled
2746
with a separate message ("Showing X to itself would accomplishing
2747
nothing").
2748
2749
</div>
2750
2751
<!------------------->
2752
<div class=entry>
2753
2754
REMOVE <i>dobj</i> now uses a separate reply if the object is already
2755
being held: "There's nothing to remove the X from."  In the past, the
2756
command was unconditionally turned into TAKE <i>dobj</i>, which showed
2757
"(from you)" as the implied indirect object part, which was a bit
2758
awkward. 
2759
2760
</div>
2761
2762
<!------------------->
2763
<div class=entry>
2764
2765
When the THROW <i>direction</i> command is used with a nonportable
2766
object (as in THROW DESK EAST), the result is now the same as for
2767
commands like MOVE and PUSH: "The desk cannot be moved."
2768
2769
</div>
2770
2771
<!------------------->
2772
<div class=entry>
2773
2774
The default response for THROW DOWN has been changed to use the same
2775
message as for DROP when applied to an object that's not currently
2776
being held: "You're not carrying that."
2777
2778
</div>
2779
2780
<!------------------->
2781
<div class=entry>
2782
2783
In statusLine.beginStatusLine(), in the StatusModeApi case, there was
2784
some leftover old code ("&lt;body bgcolor=statusbg text=statustext&gt;")
2785
right after the call to setColorScheme() that effectively undid the
2786
color settings made in setColorScheme().  The old code has been deleted.
2787
2788
</div>
2789
2790
<!------------------->
2791
<div class=entry>
2792
2793
The library now uses the same default message in response to a command
2794
to throw the player character in a direction (as in THROW ME EAST) as
2795
it does as for THROW ME AT <i>something</i>.
2796
2797
</div>
2798
2799
<!------------------->
2800
<div class=entry>
2801
2802
A new Thing method, adjustThrowDestination(), gives a prospective
2803
landing site for a thrown object a chance to redirect the landing to
2804
another object.  getHitFallDestination() now treats the result it
2805
calculates using getDropDestination() as tentative, and calls this new
2806
method on the tentative result object to determine the actual
2807
destination.  The default implementation of the new method in Thing
2808
simply returns 'self', which confirms the tentative destination as the
2809
actual destination.  BulkLimiter overrides the new method to redirect
2810
the landing site to the BulkLimiter's location's drop destination if
2811
the thrown object would overflow the BulkLimiter's capacity.
2812
2813
<p>This change corrects a problem that occurred when a thrown object
2814
landed in a BulkLimiter that was already near capacity.  In the past,
2815
the BulkLimiter applied its capacity control by effectively blocking
2816
the THROW before it happened.  With the change, the THROW will be
2817
allowed to proceed, and the thrown object will land in the nearest
2818
suitable container of the original target.
2819
2820
<p>Note that any game code that overrides getHitFallDestination()
2821
should be sure to call adjustThrowDestination() on its tentative
2822
return value.  Games usually won't have any reason to override
2823
getHitFallDestination(), so this change shouldn't affect most existing
2824
code.
2825
2826
2827
</div>
2828
2829
<!------------------->
2830
<div class=entry>
2831
2832
In ActorState, the beforeTravel() method no longer ends the current
2833
conversation if the actor is merely moving between nested locations
2834
within the same top-level location.  These aren't usually true
2835
departures that should trigger conversation termination, so the method
2836
no longer treats them as such.
2837
2838
</div>
2839
2840
<!------------------->
2841
<div class=entry>
2842
2843
A new travel connector class, DeadEndConnector, can be used for
2844
situations where travel through the connector is impossible, but for
2845
reasons that can only be learned by attempting to go through the
2846
connector.  For example, this can be used for a passage that turns out
2847
to be blocked by a cave-in that isn't visible from the passage
2848
entrance, or in a situation where you describe the actor as wandering
2849
around in a direction for a while but giving up and returning to the
2850
point of origin.
2851
2852
<p>DeadEndConnector supplements FakeConnector, which is most useful
2853
for exits that look like connections but can't be traversed for
2854
reasons that are apparent before the travel is ever physically
2855
attempted - in particular, for motivational reasons ("You can't leave
2856
town without finding your missing brother").  DeadEndConnector differs
2857
from FakeConnector in that DeadEndConnector acts as though the
2858
physical travel were actually occurring.  It fires all of the normal
2859
travel notifications, so any side effects that would occur on ordinary
2860
travel will also occur with a DeadEndConnector.
2861
2862
</div>
2863
2864
<!------------------->
2865
<div class=entry>
2866
2867
"Push travel" has been changed slightly to handle situations where the
2868
object being pushed has side effects that affect the description of
2869
the destination location.  The most common situation where this arises
2870
is when the object being pushed is (or contains) a light source, but
2871
it could happen in many other custom-coded situations.
2872
2873
<p>In the past, the object being pushed wasn't moved to its new
2874
location until after the new location had been described.  The point
2875
of this sequencing was to exclude the pushed object from the new
2876
location's description, simply by keeping it out of the new location
2877
until after the description was displayed.  This exclusion is
2878
desirable because it would otherwise look as though the pushed object
2879
were already in the new location on the player character's arrival,
2880
which would be confusing.  However, it prevented any side effects of
2881
the pushed object's presence from being taken into account in the new
2882
location's description.  If the pushed object was a light source, for
2883
example, and the new location was otherwise unlit, the new location
2884
was described as dark.
2885
2886
<p>Now, the library tentatively moves the pushable object to the
2887
destination of the travel, and marks the object (via the new
2888
Actor.excludeFromLookAround mechanism) for exclusion from the location
2889
description.  It then moves the actor and shows the description of the
2890
new location.  Finally, it moves the pushable back to the origin
2891
location, and then moves a second time, this time for real, to the
2892
destination location.
2893
2894
<p>(The reason for moving the pushable twice - first tentatively,
2895
before the travel, then again "for real," after the travel - is that
2896
the method that makes the final move is overridable and so might
2897
actually do something other than move the pushable to the travel
2898
destination.  Even if it leaves the object unmoved, though, or moves
2899
it to a different final destination, the tentative first move is still
2900
a valid intermediate step.  At the point we're generating the
2901
description of the new room, the player character is <i>in the
2902
process</i> of pushing the pushable into the new room - the PC is
2903
notionally walking along with the pushable at that stage.  If the
2904
overridable final-move method wants to do something different, it can
2905
do so; it will simply have to describe the change, which it had to do
2906
in the past anyway.  At that point, the PC will already be in the new
2907
location, and so will in fact have pushed the pushable this far;
2908
anything that happens in the overridable method happens <i>after</i>
2909
the intermediate stage where we generated the description, so any side
2910
effects of the pushable's tentative presence were valid at that point,
2911
no matter what happens afterwards.)
2912
2913
</div>
2914
2915
<!------------------->
2916
<div class=entry>
2917
2918
In the English library, the Push-Travel commands (PUSH X NORTH, PUSH X
2919
UP RAMP, etc) now only accept single direct objects.  In the past, the
2920
grammar phrasings allowed direct object lists, but actually pushing
2921
multiple objects into a new room is a practical impossibility, so
2922
there's no point in accepting it in the grammar.
2923
2924
</div>
2925
2926
<!------------------->
2927
<div class=entry>
2928
2929
The mechanism for describing "local" NPC travel has been enhanced.
2930
Local NPC travel is travel where an NPC moves from one top-level
2931
location to another, and both top-level locations are in view of the
2932
PC.  In these cases, special handling is needed because the NPC isn't
2933
truly arriving or departing in the usual sense; the NPC is instead
2934
moving closer to, further away from, or laterally with respect to, the
2935
PC.
2936
2937
<p>In the past, the local NPC travel mechanism did everything via the
2938
"local arrival" message: the NPC generated only this one special
2939
message at the destination end of the travel.  The new mechanism adds
2940
two messages analogous to the local arrival message: a "local
2941
departure" message and a "remote travel" message.  Here's how they're
2942
used:
2943
2944
<ul>
2945
2946
<li>If the PC is moving <i>closer</i> to the PC, the <b>local
2947
arrival</b> message is displayed at the destination end of the travel.
2948
"Closer" means that the NPC is moving from a top-level location that
2949
<i>doesn't</i> contain the PC to a top-level location that does
2950
contain the PC.
2951
2952
<li>If the PC is moving <i>further away</i> from the PC, the <b>local
2953
departure</b> message is displayed at the origin end of the travel.
2954
"Further away" means that the NPC is moving from the top-level
2955
location that contains the PC to a different top-level location that
2956
doesn't.
2957
2958
<li>If the PC is moving <i>laterally</i>, the <b>remote travel</b>
2959
message is displayed at the destination end of the travel.
2960
"Laterally" means that the NPC is moving between two top-level
2961
locations, neither of which contain the PC.  Note that there's no good
2962
basis for preferring to show the message on the origin or destination
2963
side of the travel in this case, since the generic situation is so
2964
symmetrical, but at the same time it's necessary to choose one or the
2965
other because we don't want two messages for this kind of travel.  So,
2966
we have to make an arbitrary choice, and the library chooses to show
2967
the message on the destination side.
2968
2969
</ul>
2970
2971
<p>These new rules obviously require some new methods.  Here's the
2972
new arrangement of methods:
2973
2974
<ul>
2975
2976
<li>The local arrival message is embodied in
2977
TravelConnector.describeLocalArrival(), which by default calls
2978
Traveler.sayArrivingLocally(), which by default calls
2979
libMessages.sayArrivingLocally().  Note that these aren't new - this
2980
part of the mechanism carries forward unchanged from past versions.
2981
However, their <i>usage</i> has changed, in that the library in the
2982
past called the local arrival messages in <i>all</i> cases of local
2983
travel, but now calls it only in <i>certain</i> cases, as described
2984
above, and calls the local-departure or remote-travel methods in other
2985
cases that formerly all folded into the local-arrival case.
2986
2987
<li>The local departure message is embodied in
2988
TravelConnector.describeLocalDeparture(), which by default calls
2989
Traveler.sayDepartingLocally(), which by default calls
2990
libMessages.sayDepartingLocally().  These methods are new.
2991
2992
<li>The remote travel message is embodied in
2993
TravelConnector.describeRemoteTravel(), which by default calls
2994
Traveler.sayTravelingRemotely(), which by default calls
2995
libMessages.sayTravelingRemotely().  These methods are new.
2996
2997
</ul>
2998
2999
<li>Existing code should continue to work correctly with the new
3000
framework, although with one caveat: if you customized a
3001
describeLocalArrival() or sayArrivingLocally() method, you might want
3002
to add corresponding customizations for the new local-departure and/or
3003
remote-travel methods.  If you don't, your local-arrival customization
3004
will still work in the cases where it applies under the new rules, but
3005
it won't be invoked in all the cases it was in the past.
3006
3007
</div>
3008
3009
<!------------------->
3010
<div class=entry>
3011
3012
AccompanyingInTravelState now describes local travel using its
3013
standard departure message.  This ensures that the correct messages
3014
are displayed when accompanying an actor in local travel or travel
3015
between two connected top-level locations (such as locations linked by
3016
distance).
3017
3018
</div>
3019
3020
<!------------------->
3021
<div class=entry>
3022
3023
TravelAction.actionOfKind(cls) now properly handles the case where
3024
'cls' is the base TravelAction class.  (In the past, asking about
3025
TravelAction itself caused a run-time error.)
3026
3027
</div>
3028
3029
<!------------------->
3030
<div class=entry>
3031
3032
The various SettingsItem objects defined in the library are now all
3033
named objects.  In the past, some of these (such as
3034
gameMain.verboseMode) were defined as embedded objects; this made it
3035
more difficult to modify their behavior, since it wasn't possible to
3036
use 'modify' to alter the objects directly.  The behavior should be
3037
exactly the same as in the past; the only difference is that the
3038
objects are now easier to customize.
3039
3040
</div>
3041
3042
<!------------------->
3043
<div class=entry>
3044
3045
The putDestMessage that was defined in defaultFloor and defaultGround
3046
has been moved to the base Floor class instead - this message should
3047
be common to most floor/ground type objects, not just for the default
3048
ones in the library.
3049
3050
</div>
3051
3052
<!------------------->
3053
<div class=entry>
3054
3055
The method standing.tryMakingPosture(loc) now generates the command
3056
STAND ON <i>loc</i>, rather than simply STAND as it did in the past.
3057
This makes the behavior consistent with the sitting and lying postures.
3058
3059
</div>
3060
3061
<!------------------->
3062
<div class=entry>
3063
3064
Room can now be used as the direct object of STAND ON, SIT ON, and LIE
3065
ON.  These are handled simply by remapping the commands to the room's
3066
"floor" object (specifically, the object returned from the room's
3067
roomFloor method).  This is in part to accommodate the change above to
3068
standing.tryMakingPosture(), and in part to provide better automatic
3069
handling for player commands like SIT IN YARD.
3070
3071
</div>
3072
3073
<!------------------->
3074
<div class=entry>
3075
3076
RoomPart now applies some additional disambiguation filtering in cases
3077
where two or more top-level locations are linked by a sense connector.
3078
When a resolve list contains multiple RoomPart objects, and some of
3079
those RoomParts are local and some remote, RoomPart will reduce the
3080
list to include only the local RoomParts.  (A "local" object is one
3081
within the same top-level location as the actor; a "remote" object is
3082
one that's in a separate top-level location that's linked by a sense
3083
connector.)
3084
3085
</div>
3086
3087
<!------------------->
3088
<div class=entry>
3089
3090
If a RoomPart has an explicit 'location' setting, that location will
3091
no longer add the RoomPart redundantly to the location's 'contents'
3092
list.  In the past, the RoomPart would show up twice in the contents
3093
list, because it was added once by virtue of being in the RoomParts
3094
list, and again by virtue of its 'location' setting.
3095
3096
<p>In addition, when a RoomPart has an explicit 'location' setting, it
3097
will now automatically add itself to that location's 'roomParts' list.
3098
This means that you don't have to manually set both properties, which
3099
saves a little work and also makes your game easier to maintain, since
3100
you won't have to remember to make coordinated changes to both
3101
settings in your source code if you change the room part later.
3102
3103
</div>
3104
3105
<!------------------->
3106
<div class=entry>
3107
3108
RoomPart and TravelConnectorLink now have a default sightSize of
3109
'large'.  This means that it's possible to examine these objects at a
3110
distance.  Room parts are things like walls and ceilings that tend to
3111
be large and to contain large-scale details that would be
3112
realistically discernible at a distance - the details are typically
3113
things like doors and windows.  Similarly, TravelConnectorLink (which
3114
you'd mainly use via its subclasses Enterable and Exitable) is for
3115
things like building exteriors, which likewise tend to have
3116
large-scale details.
3117
3118
<p>In cases where you create a RoomPart or an Enterable or Exitable
3119
that has fine-grained details that would be too small to see at a
3120
distance, <i>and</i> the object is visible from a separate top-level
3121
location linked by distance, you might want to override this to set
3122
the sightSize back to medium.  When there's no distance-linked
3123
top-level location, this shouldn't be an issue, since there'd be no
3124
way to examine the object from a distance to begin with.
3125
3126
</div>
3127
3128
<!------------------->
3129
<div class=entry>
3130
3131
RoomPartItem now overrides useSpecialDescInRoom() and
3132
useSpecialDescInContents() to return nil, and no longer overrides
3133
useSpecialDesc and useInitSpecialDesc.
3134
3135
<p>In the past, RoomPartItem overrode useSpecialDesc and
3136
useInitSpecialDesc (setting them to nil) in order to prevent room part
3137
items from being included in LOOK descriptions, but this had the bad
3138
side effect of preventing showSpecialDesc() from showing the
3139
initSpecialDesc.  This change uses the more precise methods to select
3140
exactly where the special desc should be shown, without affecting the
3141
selection of which special desc to show.
3142
3143
</div>
3144
3145
<!------------------->
3146
<div class=entry>
3147
3148
Thing.isListedInContents now calls useSpecialDescInContents(location)
3149
to make its determination.  In the past, it called useSpecialDesc
3150
directly; this was incorrect because it didn't properly take into
3151
account the differentiation among contexts that the various
3152
useSpecialDescInXxx methods provide.
3153
3154
</div>
3155
3156
<!------------------->
3157
<div class=entry>
3158
3159
The exit-list generator (exitLister.showExitsWithLister) now considers
3160
two destination locations to be equivalent based on the destination
3161
room object rather than the destination room name.  This means that
3162
two distinct exit locations will now be listed separately even if they
3163
have the same name.  For example, in the past, if the east and west
3164
exits led to separate rooms that both happened to be named "the
3165
hallway," the listing formerly read "east (or west), to the hallway",
3166
but will now read "east, to the hallway; west, to the hallway".  The
3167
old approach of merging list entries based on name alone produced odd
3168
results in some cases, and didn't have any obvious benefits; the new
3169
approach should produce more predictable results.
3170
3171
</div>
3172
3173
<!------------------->
3174
<div class=entry>
3175
3176
TIAction has a new method, retryWithAmbiguousIobj(), that lets an
3177
action handler specifically ask for disambiguation from a list of
3178
possibilities.  This is the TIAction equivalent of the TAction method
3179
retryWithAmbiguousDobj(), and works the same way; the only difference
3180
is that the disambiguation list applies to the indirect object rather
3181
than to the direct object.
3182
3183
</div>
3184
3185
<!------------------->
3186
<div class=entry>
3187
3188
The TAction and TIAction methods retryWithAmbiguousDobj() and
3189
retryWithAmbiguousIobj() can now be called before the "iteration"
3190
phase of the command execution, specifically during
3191
Action.beforeActionMain(), and they'll work properly: they'll ask
3192
their disambiguation question, then apply it to the entire iteration
3193
for the other object list.  For example, if you call
3194
retryWithAmbiguousIobj() during beforeActionMain() to prompt for a new
3195
indirect object for a PUT IN command, the player's response will
3196
automatically be applied to the whole direct object list if the player
3197
specified multiple direct objects.  In the past, it wasn't possible to
3198
call these "retry" methods during beforeActionMain(), so if they were
3199
used during commands with multiple objects in the other object slot,
3200
the result was that the "retry" - and its question to the user - was
3201
repeated for each object in the list.
3202
3203
<p>(This new flexibility involves two supporting changes.  First, the
3204
various initForMissingXxx() methods in various Action subclasses now
3205
detect that the iteration over the object list hasn't begun yet, and
3206
they simply retain the entire object list (rather than the current
3207
iteration item, as they did in the past) for the retry.  Second, to
3208
support the first change, the class PreResolvedAmbigProd now accepts
3209
an entire object list instead of just a single iteration element.
3210
These are internal methods that game code is unlikely to call
3211
directly, so the only visible effect of these changes should be the
3212
new flexibility in how the "retry" methods can be used.)
3213
3214
</div>
3215
3216
<!------------------->
3217
<div class=entry>
3218
3219
In the past, initializeThing() was sometimes called multiple times in
3220
the course of dynamically creating an object (with 'new').  This
3221
happened when creating objects based on classes that inherited from
3222
Thing more than once (classes like this include Flashlight, Passage,
3223
Room, Chair, Bed, Platform, NominalPlatform, Booth, and
3224
UntakeableActor).  This happened because the default constructor for
3225
any object based on multiple base classes simply inherits each of the
3226
base class constructors, one after the other; when more than one base
3227
class itself inherits from Thing, this results in multiple inherited
3228
invocations of the Thing constructor, which in the past resulted in
3229
multiple invocations of initializeThing() for the new object.
3230
3231
<p>Now, initializeThing() is only called once.  The Thing constructor
3232
now tests a flag before calling initializeThing; it only calls the
3233
method if the flag isn't set, and it sets the flag after calling the
3234
method.  This ensures that subsequent inherited constructor calls
3235
simply skip the call to initializeThing().  The constructor also skips
3236
the call to its own inherited base class constructor when the flag is
3237
set; this ensures that the vocabulary initializations in VocabObject
3238
are only invoked once per object.
3239
3240
</div>
3241
3242
<!------------------->
3243
<div class=entry>
3244
3245
Room has a few command-handling enhancements, for rooms that have
3246
associated vocabulary.  LOOK IN <i>room</i> is now treated the same as
3247
EXAMINE <i>room</i>; LOOK UNDER and LOOK BEHIND are refused ("You
3248
can't look under that"); SMELL and LISTEN TO <i>room</i> are now
3249
equivalent to simply SMELL and LISTEN; BOARD and ENTER are treated as
3250
redundant ("You're already in that"); and GET OUT OF is a little
3251
smarter about remapping, so that it only remaps to GO OUT if there
3252
actually is an OUT direction defined for the room, and fails with an
3253
error if not ("You'll have to say which way to go").
3254
3255
</div>
3256
3257
<!------------------->
3258
<div class=entry>
3259
3260
NestedRoom.makeStandingUp() now leaves the actor's posture unchanged
3261
if the travel to the new location fails.  It does this by noting the
3262
original posture before the travel attempt, and checking after the
3263
travel attempt to see if the actor is still in the starting nested
3264
room; if so, the routine restores the saved posture.  This ensures
3265
that a failed travel attempt won't cause a posture change in the
3266
original nested location.
3267
3268
</div>
3269
3270
<!------------------->
3271
<div class=entry>
3272
3273
NominalPlatform now overrides hideFromDefault() to always return true.
3274
Nominal platforms are meant to be used as internal objects and not to
3275
appear as simulation objects, so it's generally not desirable for them
3276
to be used as defaults.
3277
3278
</div>
3279
3280
<!------------------->
3281
<div class=entry>
3282
3283
AccompanyingState had a problem that caused infinite recursion
3284
(leading to a stack overflow) when an actor in an AccompanyingState
3285
was explicitly moved via scriptedTravelTo().  The problem was simply
3286
that the actor attempted to accompany itself on its own travel, and
3287
that accompanying travel triggered a further accompanying travel, and
3288
so on.  This has been corrected: actors in accompanying travel states
3289
now explicitly ignore their own travel for the purposes of
3290
accompanying travel.
3291
3292
</div>
3293
3294
<!------------------->
3295
<div class=entry>
3296
3297
The library uses a separate default message in cases where an Actor is
3298
holding an object used in ENTER, BOARD, SIT ON, etc.  In the past, the
3299
message was the rather awkward "You can't do that while the chair in
3300
in Bob."  The new message is phrased "...while Bob is holding the
3301
chair" instead.  The default message for non-Actors is unchanged.
3302
3303
</div>
3304
3305
<!------------------->
3306
<div class=entry>
3307
3308
FOLLOW caused a run-time error if the follower was holding the
3309
NPC to be followed.  This was because effectiveFollowLocation
3310
wasn't defined for ordinary objects.  This has been corrected
3311
by defining Thing.effectiveFollowLocation to return the location's
3312
effectiveFollowLocation, or just 'self' if the object has no
3313
location.
3314
3315
</div>
3316
3317
<!------------------->
3318
<div class=entry>
3319
3320
<a name='ImpByeTopicSubclasses'></a>
3321
3322
There are two new subclasses of ImpByeTopic, to allow you to
3323
differentiate between the two implicit ways of ending a conversation.
3324
BoredByeTopic handles cases where the NPC ends the conversation
3325
because of "boredom" (that is, inactivity in the conversation that
3326
exceeds the NPC's attentionSpan setting), while LeaveByeTopic handles
3327
cases where the PC simply walks away from the NPC in mid-conversation.
3328
3329
<p>BoredByeTopic and LeaveByeTopic extend the hierarchy that already
3330
existed with ByeTopic and ImpByeTopic.  If there's an active
3331
ImpByeTopic and no active BoredByeTopic or LeaveByeTopic objects at
3332
the time of an implied "goodbye", the ImpByeTopic will be used for
3333
both cases (this also happens to be exactly the way the library worked
3334
in the past, before the two new subclasses were added, so this change
3335
won't disturb existing code).  If there's an active BoredByeTopic as
3336
well as an active ImpByeTopic, the BoredByeTopic will be selected over
3337
the ImpByeTopic to handle "boredom" goodbyes; likewise, if there's an
3338
active LeaveByeTopic, it will be selected over an active ImpByeTopic
3339
to handle goodbyes triggered by the PC's departure.
3340
3341
</div>
3342
3343
<!------------------->
3344
<div class=entry>
3345
3346
The "boredom" mechanism in InConversationState has been changed
3347
slightly.  In the past, it was implemented directly in the takeTurn()
3348
method of InConversationState.  Now, it's handled with an AgendaItem
3349
instead - specifically, a new subclass called BoredomAgendaItem, which
3350
the Actor and InConversationState classes manage automatically.  This
3351
change should have no effect on existing code, since the new code
3352
implements the same behavior as the old version.  The benefit of this
3353
change is that it makes it easier for a game to customize the boredom
3354
behavior, since it's now part of the more general "agenda" mechanism
3355
instead of being buried in ad hoc code inside the conversation state
3356
class.
3357
3358
</div>
3359
3360
<!------------------->
3361
<div class=entry>
3362
3363
The suggested topic lister had a problem that showed up when several
3364
topic suggestions were present with the same listing name, and some of
3365
the topics were inactive while others were active.  The lister
3366
automatically removes redundant entries from suggestion lists by
3367
removing multiple items with the same name, but in the past, the
3368
lister sometimes incorrectly removed the <i>active</i> elements
3369
instead of the inactive ones, effectively eliminating the suggestion
3370
entirely from the list.  This has been corrected: the lister now only
3371
removes a redundant suggestion if there's another <i>active</i>
3372
suggestion with the same listing name.
3373
3374
</div>
3375
3376
<!------------------->
3377
<div class=entry>
3378
3379
InitiateTopic no longer sets any pronoun antecedents when triggered.
3380
(It did set its match object as a pronoun antecedent in the past.
3381
This was undesirable because an InitiateTopic is triggered by internal
3382
calculations in the game, not by anything the player has done.)
3383
3384
</div>
3385
3386
<!------------------->
3387
<div class=entry>
3388
3389
ConvAgendaItem now checks to make sure the player character is present
3390
before declaring itself ready.  This ensures that an NPC won't attempt
3391
a conversational agenda item unless the PC is actually present to hear
3392
what the NPC has to say.  (This change is in ConvAgendaItem.isReady.)
3393
3394
</div>
3395
3396
<!------------------->
3397
<div class=entry>
3398
3399
Actor.executeAgenda() formerly marked an agenda item as done if
3400
invoking the item threw any sort of exception.  Now, this is only done
3401
on a run-time error (a RuntimeError exception); in cases of other
3402
exceptions, the item's doneness isn't changed.  The original purpose
3403
of the doneness change was to reduce debugging hassles in cases where
3404
an agenda item encountered an error; in such cases, if the item wasn't
3405
marked as done, the scheduler would end up invoking the item in an
3406
infinite loop, because it would look perpetually ready to run.
3407
However, doing this on <i>all</i> exceptions interfered with certain
3408
non-error cases where exceptions were used to jump out of the action
3409
handling.  Limiting the caught exceptions to runtime errors should
3410
retain most of the intended benefits while avoiding the problems with
3411
a more general error catcher here.
3412
3413
</div>
3414
3415
<!------------------->
3416
<div class=entry>
3417
3418
Actor.initiateConversation() now handles a nil 'state' argument
3419
slightly differently.  In the past, if 'state' was nil, the actor's
3420
state was simply left unchanged.  Now, the method will switch the
3421
actor to the state returned from the current state's
3422
getImpliedConvState() method.  In most cases, the net effect is
3423
exactly as before - i.e., the actor's state is left unchanged -
3424
because the default getImpliedConvState() simply returns 'self'.
3425
However, ConversationReadyState overrides getImpliedConvState() to
3426
return the associated InConversationState.  This change makes it
3427
easier to initiate a conversation when using an actor with
3428
conversational states, since it will generally pick the correct
3429
conversational state automatically.
3430
3431
<p>Note that the ActorState method getImpliedConvState() is new with
3432
this change.
3433
3434
</div>
3435
3436
<!------------------->
3437
<div class=entry>
3438
3439
Due to a bug, &lt;.convnode&gt; tags displayed inside npcGreetingMsg
3440
methods weren't handled properly if the greeting was displayed due to
3441
NPC initiation of the conversation (via npcInitiateConversation()).
3442
This has been corrected.
3443
3444
</div>
3445
3446
<!------------------->
3447
<div class=entry>
3448
3449
ConvNode.canEndConversation() can now return a special value,
3450
blockEndConv, that indicates that the actor said something to force
3451
the conversation to keep going.  You should always use this if you
3452
display a message in the routine <i>and</i> you want to prevent the
3453
conversation from ending.  Returning blockEndConv is <i>almost</i> the
3454
same as returning nil from the method, but has the additional side
3455
effect that the caller will call noteConvAction() on the other actor,
3456
to prevent this actor from generating any further scripted remarks on
3457
the same turn.
3458
3459
</div>
3460
3461
<!------------------->
3462
<div class=entry>
3463
3464
When the library displays a parser error message for a command
3465
directed to an NPC, it now shows the error message in a neutral sense
3466
context.  This ensures that the message is displayed even if the NPC
3467
is in a remote location (this could be the case if we're talking over
3468
the phone, for example).  In the past, the parser message was
3469
generated in the NPC's sense context, so the NPC was in a remote
3470
location that wasn't in scope to the PC, the parser message was
3471
suppressed, resulting in a "Nothing happens" message or the like.
3472
3473
</div>
3474
3475
<!------------------->
3476
<div class=entry>
3477
3478
When a command of the form "actor, xxx" is entered, and the portion
3479
after the "actor" phrase is unparseable, the parser now attempts to
3480
parse at least the "actor" part to determine if the command is being
3481
directed to an NPC.  In the past, the parser didn't do this; the actor
3482
phrase is part of the basic sentence grammar, so if the parser failed
3483
to match the rest of the basic sentence grammar, it didn't bother
3484
trying to figure out if a target actor was included.  To find the
3485
target actor, the parser now makes a second attempt at parsing a
3486
command to see if it matches a very basic sentence syntax that only
3487
includes the target actor specification; if it can match the syntax,
3488
and resolve the noun phrase to an in-scope actor, the parser takes
3489
the result to be the target actor.
3490
3491
<p>The main result of this change is that a few of the low-level
3492
parser message methods - askUnknownWord, specialTopicInactive,
3493
commandNotUnderstood - are now invoked on the target actor when one is
3494
present in the command.  In the past, because the parser didn't even
3495
figure out that a target actor was present in these cases, these
3496
methods were always invoked on the player character actor.  With this
3497
change, it's now possible to customize a NPC's responses for unknown
3498
words and command phrasings individually by NPC.
3499
3500
</div>
3501
3502
<!------------------->
3503
<div class=entry>
3504
3505
The library now gives a replacement action zero time if it's replacing
3506
an action that itself has zero time.  This corrects some timing
3507
anomalies (particularly with respect to NPCs) that showed up in
3508
certain unusual cases where replaceAction() was used in the course
3509
of an action that itself was being run as a nested action.
3510
3511
</div>
3512
3513
<!------------------->
3514
<div class=entry>
3515
3516
A new parser option lets you cancel remaining commands on the command
3517
line when an action fails.
3518
3519
<p>To implement this, Action.afterActionMain() checks to see if the
3520
action failed, as indicated by a 'reportFailure()' message in the
3521
course of the action handling.  If the action failed, <i>and</i>
3522
gameMain.cancelCmdLineOnFailure is set to true, afterActionMain()
3523
throws a CancelCommandLineException.  This exception is in turn caught
3524
in executeCommand(), which cancels any remaining commands on the
3525
command line and simply proceeds to the next turn.
3526
3527
<p>In addition, the new playerMessages method
3528
explainCancelCommandLine() lets you display an explanation when a
3529
command line is canceled due to the failure of a command.
3530
executeCommand() invokes this new method when it handles a
3531
CancelCommandLineException if there are in fact any remaining tokens
3532
on the command line.  (This check for remaining tokens skips the
3533
explanation when there's nothing left on the command line to cancel,
3534
as the cancellation obviously has no effect in such cases.)  This new
3535
message method doesn't display anything by default; it's just a hook
3536
that you can use if you want to provide an explanation.  Note that
3537
you'll probably want to show this explanation only once per game,
3538
rather than every time a command is canceled (you can use a flag
3539
property to do this - if the flag is nil, show the message and set the
3540
flag to true; otherwise skip the message).
3541
3542
<p>The default setting for gameMain.cancelCmdLineOnFailure is nil.
3543
This provides the traditional handling, which simply continues executing
3544
any remaining commands on the command line even when an action fails.
3545
3546
<p>The reason this new feature is an option rather than simply being
3547
the default new policy is that neither possibility is ideal in every
3548
case.  On the one hand, continuing to execute commands after an action
3549
has failed can lead to confusing results: the failure of the earlier
3550
command can leave things in a state other than what the player was
3551
anticipating, which could change the behavior of subsequent commands.
3552
So the argument in favor of canceling remaining commands is that it
3553
avoids this possible source of player confusion by halting processing
3554
once it appears that the player's thinking is out of sync with the
3555
game's internal state.  On the other hand, exactly what constitutes
3556
failure might not always be apparent to the player, so halting halfway
3557
through a command line might sometimes appear arbitrary to the player,
3558
or even buggy.  The argument in favor of continuing to plow through
3559
the rest of the command line like nothing happened, then, is that it's
3560
simple and consistent.  A prime virtue of any UI is predictability, so
3561
that the user has an easier time forming a working mental model of the
3562
software, and the most predictable behavior is to unconditionally
3563
execute everything on the command line.  Further, given that
3564
multi-level UNDO is available by default in tads3 games, any
3565
unintended effects from extra commands can always be manually undone
3566
as soon as the player realizes what happened.  The arguments on both
3567
sides are valid, so the library leaves it up to the author to set the
3568
game's policy.  (It's even been suggested that this ought to be left
3569
up to the player, via a command that selects the mode, but I think
3570
this would be overkill, so for now this is just an author-controlled
3571
option.  Games are free to add their own command to let the player
3572
control it, of course; it's just a matter of flipping the
3573
cancelCmdLineOnFailure setting at run-time.)
3574
3575
</div>
3576
3577
<!------------------->
3578
<div class=entry>
3579
3580
The Action class has a new method, checkAction(), that is called just
3581
before the existing execAction() method.  TAction and TIAction define
3582
the new method, and perform the calls to the direct and indirect
3583
object 'check' methods in this new method rather than in execAction(),
3584
as was done in the past.
3585
3586
<p>This change should have no effect on existing code, since it's a
3587
simple internal rearrangement.  The benefit is that it's now possible
3588
for game code to call the 'check' phase of a verb explicitly, without
3589
also invoking the 'execute' phase.
3590
3591
</div>
3592
3593
<!------------------->
3594
<div class=entry>
3595
3596
OopsIAction is now defined as an IAction.  (In the past, it was based
3597
directly on Action, which was problematic if an OopsIAction grammar
3598
match was used in certain contexts, such as
3599
CommandRanking.sortByRanking.)
3600
3601
</div>
3602
3603
<!------------------->
3604
<div class=entry>
3605
3606
ObjectPreCondition now uses the same ordering as the underlying
3607
condition.
3608
3609
</div>
3610
3611
<!------------------->
3612
<div class=entry>
3613
3614
During calls to the "verify" methods for remapped actions (i.e.,
3615
actions mapped to different actions using remapTo), the library now
3616
sets gAction to the remapped action.  In the past, during the initial
3617
remap testing stage, the library left gAction with the original action
3618
that triggered the remapping.  This gives game code more consistent
3619
information during the verify phase.
3620
3621
</div>
3622
3623
<!------------------->
3624
<div class=entry>
3625
3626
VocabObject now defines the methods isOwnedBy(obj) and
3627
getNominalOwner().  This allows player input to refer to non-physical
3628
objects, such as topics, using possessive syntax.
3629
3630
</div>
3631
3632
<!------------------->
3633
<div class=entry>
3634
3635
The INSTRUCTIONS command is now ignored for the purposes of UNDO and
3636
AGAIN.
3637
3638
</div>
3639
3640
<!------------------->
3641
<div class=entry>
3642
3643
The parser no longer chooses Unthings as default objects in cases
3644
where noun phrases are missing in player input.  (This is handled via
3645
Unthing.hideFromDefault().)
3646
3647
</div>
3648
3649
<!------------------->
3650
<div class=entry>
3651
3652
The new Thing method setGlobalParamName() lets you add a global
3653
message parameter name dynamically.  In the past, there was no
3654
straightforward way to do this; you had to manually update the message
3655
builder's internal table of names in order to add a new name.  This
3656
method takes care of all of the necessary internal table updates.
3657
3658
<p>You only need to use this method if you want to add or change a
3659
parameter name dynamically at run-time.  The library still
3660
automatically initializes the message builder's tables for
3661
globalParamName settings defined at compile-time.
3662
3663
</div>
3664
3665
<!------------------->
3666
<div class=entry>
3667
3668
The parser now marks a plural-phrase match for a direct or indirect
3669
object as "unclearly disambiguated" if the phrase also matches a
3670
singular noun for an object that's also in scope.  This flag makes
3671
the parser generate an extra message to notify the player that the
3672
parser chose an object from a potentially ambiguous set:
3673
3674
<p><pre>
3675
  &gt;show bob the rags
3676
  (the piece of cloth)
3677
  Bob does not appear interested.
3678
</pre>
3679
3680
<p>If the parser's decision was wrong, the message will alert the
3681
player, so that the player will know to try rephrasing the command
3682
rather than being left with the impression that the intended command
3683
didn't work.
3684
3685
</div>
3686
3687
<!------------------->
3688
<div class=entry>
3689
3690
The event manager (the part of the library that manages fuses and
3691
daemons) now automatically disables a daemon or fuse that throws an
3692
exception out of its main execution method.  The reason this is
3693
important is that an infinite loop would otherwise occur in many
3694
cases: if the object remained active, the event manager would
3695
re-invoke it after the exception, and in most cases the re-invocation
3696
would simply encounter the same exception, at which point the event
3697
manager would invoke it once again, and so on ad infinitum.
3698
3699
<p>Note that this change only comes into play when a fuse/daemon
3700
throws an exception <b>out</b> of its main method.  It won't affect a
3701
daemon/fuse that merely encounters an exception in the course of its
3702
processing, as long as the fuse/daemon catches and handles the
3703
exception.
3704
3705
</div>
3706
3707
<!------------------->
3708
<div class=entry>
3709
3710
A new class, OneTimePromptDaemon, makes it easy to set up a prompt
3711
daemon that only fires once.  It works like an ordinary prompt daemon,
3712
but removes itself from the active event list as soon as it fires.
3713
This can be handy for cases where you want to defer some non-recurring
3714
processing until just before the next command prompt.
3715
3716
</div>
3717
3718
<!------------------->
3719
<div class=entry>
3720
3721
Thanks to Greg Boettcher, the English library's default messages now
3722
use typographical ("curly") quote marks and apostrophes.  In cases of
3723
open/close quote marks, these are generated with
3724
&lt;Q&gt;...&lt;/Q&gt; markups; in cases of apostrophes, &amp;rsquo;
3725
entities are used.
3726
3727
<p>This change is purely cosmetic, so it should require no changes to
3728
existing game code.  It shouldn't even affect test scripts (where you
3729
run an input script and "diff" the output against a reference log) -
3730
by default, the log file mechanism by default generates transcript
3731
output in plain ASCII, and the curly quotes are mapped to ordinary
3732
straight quotes when rendered in plain ASCII.
3733
3734
</div>
3735
3736
<!------------------->
3737
<div class=entry>
3738
3739
<a name='getInScopeDistinguisher'></a>
3740
The library now attempts to be as precise as possible when announcing
3741
objects chosen in vague disambiguations, as defaults for missing noun
3742
phrases, and for multiple objects to a verb.  In the past, the library
3743
simply used the base name of the object being announced, but this
3744
didn't take into account the various things that the parser can use to
3745
distinguish objects on input, such as lit/unlit state, location, and
3746
owner.  The library now generates these object announcements using the
3747
same Distinguisher mechanism it uses to resolve ambiguous noun phrases
3748
in input, ensuring that the generated names are as precise as possible
3749
in distinguishing announced objects from others in scope.
3750
3751
<p>To accomplish this, the announcements call upon a new Thing method,
3752
getInScopeDistinguisher().  This method looks at the Distinguisher
3753
objects associated with the object to be announced, and tries to find
3754
one that can distinguish the object to be announced from every other
3755
object in scope.  If it finds one, it returns it.  If it fails to find
3756
one, it returns the distinguisher that does the best partial job -
3757
that is, the one that distinguishes the object from the largest number
3758
of other in-scope objects.  (The method never returns nil; in the
3759
worst case, it simply returns basicDistinguisher, which distinguishes
3760
objects based on their disambigName properties.)  The announcements
3761
then use the returned Distinguisher to generate the announced name.
3762
3763
<p>Note that in the simplest case, this change results in the
3764
disambigName being used in object announcements; in the past, the base
3765
name was used.  In most cases, this won't cause any change in game
3766
behavior, since the disambigName for most objects is just the base
3767
name anyway.
3768
3769
</div>
3770
3771
<!------------------->
3772
<div class=entry>
3773
3774
The library now suppresses vague disambiguation announcements for
3775
objects specified with indefinite articles when the announcement
3776
would be redundant.  That is, if there's no Distinguisher that can
3777
tell apart any of the possible matches for an object specified with
3778
an indefinite article, the library doesn't bother making the
3779
announcement, because it would add no useful information for the
3780
player.  For example, in the past, you might have seen an exchange
3781
like this:
3782
3783
<p><pre>
3784
   &gt;take a silver coin
3785
   (the silver coin)
3786
</pre>
3787
3788
<p>The parser was making the announcement because it had chosen
3789
arbitrarily from one of several silver coins.  But since all of the
3790
possible matches were indistinguishable anyway, the announcement
3791
doesn't help the player see which one in particular was chosen.  The
3792
library now suppresses the message in this case.  Note, however, that
3793
if it's possible to distinguish any of the possible matches from one
3794
another, you'll still see a message.  For example, if there's a silver
3795
coin and a gold coin present, and the player types TAKE A COIN, the
3796
library will announce which one (gold or silver).  Similarly, if
3797
there's a silver coin on the table and another on the floor, and the
3798
player types TAKE A SILVER COIN, the library will mention the location
3799
of the one chosen: "(the silver coin on the floor)", for example.
3800
3801
</div>
3802
3803
<!------------------->
3804
<div class=entry>
3805
3806
The English library can now correctly generate a plural name for an
3807
object whose name includes an "of" phrase; for example, the library
3808
now correctly generates the plural for "piece of paper" as "pieces of
3809
paper".  In the past, the library pluralized the last word of the
3810
entire phrase, so the result in this example would have been "piece of
3811
papers".  The new algorithm when there's an "of" is simply to
3812
pluralize the last word before the first "of", using the same rules as
3813
for a phrase without "of".
3814
3815
</div>
3816
3817
<!------------------->
3818
<div class=entry>
3819
3820
In the past, the English parser treated a command of the form GIVE
3821
<i>adjective noun</i> as though it meant GIVE <i>noun</i> TO
3822
<i>adjective</i>.  This was almost never what the player actually
3823
meant; the player almost always really meant GIVE <i>object</i> TO
3824
<i>the current interlocutor</i>, where <i>object</i> is named
3825
<i>adjective noun</i>.  The parser now applies that more likely
3826
interpretation when confronted with this syntax.  The same applies to
3827
SHOW.
3828
3829
<p>(As part of this change, a new parser class was added:
3830
ImpliedActorNounPhraseProd.  This is a subclass of EmptyNounPhraseProd
3831
that works almost the same way, but doesn't apply a grammar ranking
3832
penalty for the missing noun phrase if a default interlocutor can be
3833
identified.  The single-noun-phrase grammars for GIVE and SHOW use
3834
this new class, ensuring that they're chosen over the
3835
non-prepositional two-noun-phrase phrasings whenever a default
3836
interlocutor is present.)
3837
3838
</div>
3839
3840
<!------------------->
3841
<div class=entry>
3842
3843
In the past, the English parser treated the word "of" as a non-weak
3844
token when matching noun phrases of the form "x of y".  This meant
3845
that if a noun phrase consisted only of weak tokens and "of", the
3846
parser matched it.  This has changed; "of" is now ignored for the
3847
purposes of the weak-token test, so a phrase consisting only of weak
3848
tokens and "of" is now considered weak overall.
3849
3850
</div>
3851
3852
<!------------------->
3853
<div class=entry>
3854
3855
A bug in the English library caused run-time errors in some cases
3856
involving TopicAction verbs.  The problem was that some of the
3857
TopicAction message generators assumed that they were the current
3858
active verb, which isn't always the case.  This has been fixed.
3859
3860
</div>
3861
3862
<!------------------->
3863
<div class=entry>
3864
3865
The English library defines the new verb phrasings ASK <i>actor</i>
3866
<i>topic</i> and TELL <i>actor</i> <i>topic</i>; these are phrasings
3867
for the new actions AskVague and TellVague, respectively.  These are
3868
defined entirely to provide more helpful error messages in cases where
3869
the player enters an ASK or TELL verb without an ABOUT phrase.  The
3870
default handling for the new actions simply displays an explanation of
3871
the proper ASK ABOUT or TELL ABOUT phrasing.  Some players have been
3872
seen to misinterpret custom phrasings that show up in SpecialTopic
3873
prompts, such as "ask bob why", as general-purpose command phrasing,
3874
and then attempt to use similar phrasing elsewhere in the game.  This
3875
results in "invalid command" errors from the parser, of course, but
3876
the standard error messages were often unhelpful with this particular
3877
kind of phrasing error.  The new handlers are meant to improve on the
3878
standard error messages for this common case.
3879
3880
</div>
3881
3882
<!------------------->
3883
<div class=entry>
3884
3885
The English library now treats the command phrasing CLIMB IN/INTO/IN
3886
TO as a Board action, and CLIMB ON/ONTO/ON TO as a StandOn action.  In
3887
the past, both forms of CLIMB were defined for both of these actions,
3888
which made the choice of which action matched the syntax arbitrary and
3889
unpredictable.  This change ensures that each of these phrasings is
3890
unambiguously assigned to only one action.
3891
3892
</div>
3893
3894
<!------------------->
3895
<div class=entry>
3896
3897
The English library now tries a little harder to figure out whether a
3898
command of the form ENTER <i>text</i> means ENTER <i>text</i> ON
3899
<i>some implied keypad-type object</i>, or GO IN <i>object</i>.  In
3900
the past, the library always used the GO IN interpretation.  Now, the
3901
library assumes the ENTER ON <i>keypad</i> interpretation if there's a
3902
suitable default object present; if there isn't, the library reverts
3903
to the GO IN interpretation.
3904
3905
</div>
3906
3907
<!------------------->
3908
<div class=entry>
3909
3910
The English library formerly allowed any object to match the pronoun
3911
"them"; it now limits "them" matches to (a) objects used in lists in
3912
player input, as in TAKE IRON KEY AND BRASS KEY, and (b) objects
3913
marked as having plural usage via isPlural.
3914
3915
</div>
3916
3917
<!------------------->
3918
<div class=entry>
3919
3920
The parser now lowers the grammar match ranking for any phrasing
3921
involving a plural in a noun slot requiring a single object.  This
3922
makes the parser a bit smarter about picking the right vocabulary
3923
interpretation in cases of nouns that have both singular and plural
3924
usage, such as FISH and SHEEP.
3925
3926
</div>
3927
3928
<!------------------->
3929
<div class=entry>
3930
3931
In the English library, the isHim and isHer properties are now taken
3932
into account for arbitrary Thing objects in parameter substitutions in
3933
messages.  In the past, gender was only taken into account for Actor
3934
objects; non-Actor objects were always "it" or "them" in messages.
3935
3936
</div>
3937
3938
<!------------------->
3939
<div class=entry>
3940
3941
In the English library, the Actor methods theName, theNameObj,
3942
theNamePossAdj, theNamePossNoun, aName, and aNameObj now properly
3943
handle the first-person plural case ("we", "us", "our", "ours", etc).
3944
In the past, a plural Actor with first-person referralPerson
3945
incorrectly used the singular first-person pronouns.
3946
3947
</div>
3948
3949
<!------------------->
3950
<div class=entry>
3951
3952
The PourOnto verb in the English library now correctly uses
3953
onSingleNoun as its indirect object response phrase, matching the
3954
regular grammar for the verb.  (In the past, it incorrectly used
3955
withSingleNoun as the response phrase.)
3956
3957
</div>
3958
3959
<!------------------->
3960
<div class=entry>
3961
3962
The English library now tries harder to avoid duplicating vocabulary
3963
in the lists it constructs from vocabWords properties during
3964
initialization.  First, VocabObject.inheritVocab() now avoids
3965
redundantly scanning vocabulary inherited from superclasses.  Since
3966
this routine's whole point is to explicitly scan the class hierarchy
3967
for each object and add the vocabulary inherited from each superclass,
3968
it needs to bypass the normal automatic inheritance mechanism, which
3969
it now does.  Second, initializeVocabWith() now explicitly removes
3970
duplicates from each word list it updates, to avoid duplication in
3971
cases where an object explicitly defines the same vocabulary word at
3972
multiple inheritance levels.
3973
3974
</div>
3975
3976
3977
<!------------------->
3978
<div class=entry>
3979
3980
The new function isListSubset() determines if one list is a subset of
3981
another list: that is, if every element of the first list also appears
3982
somewhere in the second list.  (This function was formerly defined as
3983
a method in the Lister class, but it's generically useful and wasn't
3984
tied in any way to Lister, so it's been broken out as a function to
3985
make it more readily accessible to other code.)
3986
3987
</div>
3988
3989
<!------------------->
3990
<div class=entry>
3991
3992
The library functions main() and mainRestore() have been enhanced to
3993
catch QuittingException signals.  These functions, of course, are the
3994
main entrypoints for the entire program - the former is for normal
3995
start-up, and the latter is for the special kind of start-up that
3996
restores a saved state directly from the operating system shell, such
3997
as when the player launches the game by double-clicking a saved-state
3998
file on the Windows desktop.  Catching QuittingException in these
3999
functions allows game code to throw QuittingException just about
4000
anywhere, without worrying about the context.  In the past, this
4001
exception was only usable after the main command loop started; in
4002
particular, it wasn't usable from startup or initialization code (such
4003
as the code that displays the game's introductory messages), because
4004
there was no handler to catch the exception in effect while that code
4005
was running.
4006
4007
</div>
4008
4009
4010
<!------------------------------- 3.0.9 --------------------------------->
4011
<div class="sepbar"><a name='309'></a>3.0.9</div>
4012
<p><b><i>Released 8/29/2005</i></b>
4013
<p>
4014
4015
<div class=firstentry>
4016
4017
<b>Minor compatibility-breaking change:</b> In the English library,
4018
the ThingState template now uses "+" rather than "@" to introduce the
4019
listingOrder property value.  The choice of punctuation here is pretty
4020
arbitrary; the reason for the change is that a consensus emerged among
4021
users that "+" would be easier to remember in this template because
4022
the other library templates generally use "+" to mark integer slots.
4023
4024
<p>If you have existing game code that defines any ThingState objects
4025
using the old template, you'll need to change the definitions to use
4026
"+" instead of "@".  Alternatively, you could put your own definition
4027
of the old ThingState template into a common header file that your
4028
game use, in which case you wouldn't have to change any of your
4029
existing object definitions; but you're probably better off just
4030
changing your code to use the new convention, since defining your own
4031
template could cause some slight confusion for other users if you
4032
should share your code in the future.
4033
4034
</div>
4035
4036
<!------------------->
4037
<div class=entry>
4038
4039
<b>Slight risk of incompatibility:</b> Thing.getDropDestination()
4040
must now accept a nil value for the 'obj' argument.  A nil value of
4041
'obj' asks for the drop destination for a "typical" object, rather
4042
than for any specific object.  In the past, it wasn't specified that
4043
'obj' could be nil, and the library never directly called the method
4044
with a nil 'obj' value, so it's possible that some existing game code
4045
might assume that 'obj' is non-nil.  You should do a quick scan of
4046
your game code for getDropDestination() definitions to ensure that
4047
they'll work properly when 'obj' is nil.  In particular, make sure
4048
that you don't evaluate any properties of 'obj' without first checking
4049
that 'obj' is non-nil:
4050
4051
<p><pre>
4052
   getDropDestination(obj, path)
4053
   {
4054
      if (obj.isReallySmall) ...;   <font color=red>// Don't do this!!!</font>
4055
      if (obj != nil &amp;&amp; obj.isReallySmall) ...; <font color=green>// Do this instead</font>
4056
   }
4057
</pre>
4058
4059
</div>
4060
4061
<!------------------->
4062
<div class=entry>
4063
4064
<b>Slight risk of incompatibility:</b> The default value of
4065
Event.eventOrder is now 100 (it was formerly 50).  This default is
4066
essentially arbitrary (since it's only important for relative
4067
ordering), but a value of 100 is more consistent with other similar
4068
ordering defaults elsewhere in the library.
4069
4070
<p>In addition, the eventOrder of the standard sense-change daemon is
4071
now 500, to ensure that the sense-change daemon runs after most other
4072
events.  The library automatically creates the sense-change daemon at
4073
game start-up; this is the daemon that displays messages about new,
4074
ongoing, or ending sounds and odors.  In the past, this daemon had
4075
default priority, so its order relative to other fuses and daemons was
4076
arbitrary.  If another fuse or daemon ran after the sense-change
4077
daemon, and made some change that affected the sensory environment, a
4078
message about the change wasn't displayed until the following turn,
4079
since the chance had already passed to generate the message on the
4080
turn during which the change actually occurred.  This change ensures
4081
that the sense-change daemon runs after most other events, so any
4082
changes that occur in daemons and fuses will be reflected in the
4083
sense-change update for the same turn.
4084
4085
<p>If you've explicitly set eventOrder for any fuses or daemons in
4086
your game, you might need to adjust the values you set.  In
4087
particular, if you set an eventOrder value between 50 and 100 for an
4088
event object to ensure that the event is processed after events that
4089
inherit the default eventOrder, you'll need to raise that value above
4090
100.  You should also consider if it's desirable for those events to
4091
run after the sense-change daemon, as they would have in the past
4092
(since the sense-change daemon used to have default priority), and if
4093
so, raise their eventOrder values to above 500.  Finally, if you have
4094
an existing eventOrder that's over 500, you might want to consider
4095
whether you still want the event to run after the sense-change daemon;
4096
if not, you should lower the value to under 500.
4097
4098
</div>
4099
4100
<!------------------->
4101
<div class=entry>
4102
4103
<b>Possibly incompatible change:</b> The parameter lists of some of
4104
the internal library routines that handle point-of-view have changed.
4105
These aren't likely to affect any existing game code, since these are
4106
mostly used only inside the library itself, but you should check your
4107
code for any mentions of these names to be sure.  You'll need to
4108
adjust any code in your game that either calls or overrides any of
4109
these methods or functions:
4110
4111
<ul>
4112
4113
<li>Thing.fromPOV() has a new parameter giving the actor who's doing
4114
the looking.
4115
4116
<li>Function pushPOV() takes a new parameter giving the actor.
4117
4118
<li>Function callFromPOV() takes a new parameter giving the actor.
4119
4120
<li>Function setPOV() takes a new parameter giving the actor.
4121
4122
<li>Function setRootPOV() takes a new parameter giving the actor.
4123
4124
</ul>
4125
4126
</div>
4127
4128
<!------------------->
4129
<div class=entry>
4130
4131
<b>Very slight risk of incompatibility:</b> In the following methods,
4132
the parameter now gives the point-of-view <i>actor</i> instead of the
4133
point-of-view object.  The POV actor and object are usually the same
4134
anyway, so the effects on existing code should be minimal.  If you
4135
actually need the POV object, you can get it with the getPOV()
4136
function.
4137
4138
<ul>
4139
<li>Thing.showRemoteSpecialDesc
4140
<li>Thing.remoteInitSpecialDesc
4141
<li>Thing.remoteSpecialDesc
4142
<li>Thing.showSpecialDescInContents
4143
<li>Thing.showObscuredSpecialDescInContents
4144
<li>Thing.showDistantSpecialDescInContents
4145
<li>Thing.showRemoteSpecialDescInContents
4146
<li>Actor.listActorPosture
4147
</ul>
4148
4149
</div>
4150
4151
4152
<!------------------->
4153
<div class=entry>
4154
4155
The new function getPOVActor() returns the "point-of-view actor."
4156
This is the actor who's doing the looking that is, the actor who's
4157
performing the action (LOOK AROUND, EXAMINE, SMELL, etc) that's
4158
generating the current description.  This is <i>usually</i>, but not
4159
always, the same as gActor, and it <i>usually</i>, but not always,
4160
returns the same object as getPOV().
4161
4162
<p>The point-of-view actor can differ from gActor in cases where game
4163
code explicitly generates a room description from the point of view of
4164
one actor in the course of processing a command given to a different
4165
actor.  In these cases, gActor will be the actor who's performing the
4166
command, and getPOVActor() will return the actor who's generating
4167
the description.
4168
4169
<p>The point-of-view actor can differ from the point-of-view object
4170
(the object returned by the getPOV() function) when the actor is
4171
observing the location being described through an intermediary object.
4172
For example, if we're generating a description of a remote room
4173
because an actor is examining a closed-circuit TV monitor showing the
4174
remote location, the point-of-view actor will be the actor who's
4175
looking at the monitor, while the point-of-view object will be the
4176
camera in the remote location.  Note that the POV is the camera, not
4177
the monitor: the POV is intended to be the object that's physically
4178
absorbing the light rays, or other sensory equivalents, from the
4179
surroundings being described.
4180
4181
</div>
4182
4183
<!------------------->
4184
<div class=entry>
4185
4186
The library now selects remote descriptions for rooms and other
4187
objects a little differently than before.  In the past, the remoteness
4188
of the point-of-view object was the deciding factor - that is, remote
4189
descriptions were used when the POV wasn't in the same room as the
4190
object being described.  Now, the library bases the decision on the
4191
point-of-view actor, not the POV object: if the actor who's doing the
4192
looking isn't in the same room, the remote description is used.  This
4193
means, for example, that the remote description will be generated when
4194
observing a room through a closed-circuit TV system: even though the
4195
POV (the camera) is in inside the room being described, the actor
4196
who's observing the TV monitor is in a different room, so the remote
4197
description is used.
4198
4199
<p>This change is implemented in Thing.showSpecialDescWithInfo()
4200
and Thing.showSpecialDescInContentsWithInfo().
4201
4202
</div>
4203
4204
<!------------------->
4205
<div class=entry>
4206
4207
The method Thing.lookAroundWithinContents(), which is the part of the
4208
room describer that lists the room's contents, had a bug in past
4209
versions that caused a single object to be listed twice in some
4210
unusual cases.  In particular, if the room itself had brightness 1,
4211
and it contained an object that also had brightness 1, the object was
4212
listed twice: once in a list starting "In the dark you see," then
4213
again in a list starting "The <i>room</i> contains."  The same problem
4214
occurred in a dark room if an object with brightness 1 was inside a
4215
container with brightness 1.  This has been fixed.
4216
4217
</div>
4218
4219
<!------------------->
4220
<div class=entry>
4221
4222
A new mechanism in Actor allows objects to be explicitly excluded from
4223
the "look around" description of a room.  To exclude an object, call
4224
the method excludeFromLookAround(obj) on the actor, passing in the
4225
object 'obj' to be excluded.  The object will be suppressed from room
4226
descriptions until further notice - it won't show up in any of the
4227
visible-object lists, including special descriptions, room contents
4228
lists, or nested contents lists.  To remove an object from the
4229
exclusion list, call unexcludeFromLookAround(obj).
4230
4231
<p>The exclusion that this method applies is over and above any other
4232
listing-selection mechanisms, such as obj.isListed.  It's intended
4233
mostly for ephemeral exclusions that are applied other than by the
4234
object itself, since the object itself can usually more easily control
4235
its own listability via isListed and the like.
4236
4237
</div>
4238
4239
<!------------------->
4240
<div class=entry>
4241
4242
In Thing.adjustLookAroundTable(), the point-of-view actor is no longer
4243
removed from the table; instead, just the point-of-view object is
4244
removed.  In cases where the POV and actor differ and the actor is in
4245
sight of the POV, we usually want to include the actor in the
4246
generated description.
4247
4248
<p>In addition, the method now calls adjustLookAroundTable() on the
4249
actor and POV objects, giving them a chance to make further adjustments
4250
to the table.
4251
4252
</div>
4253
4254
<!------------------->
4255
<div class=entry>
4256
4257
Suppose we have an NPC who's in scope but out of hearing range, such
4258
as when the NPC is on the other side of a transparent, soundproof
4259
window from the player character.  If the player addresses a command
4260
to the NPC, the library now uses the same error message that it uses
4261
for ASK ABOUT and other conversation commands in the same situation.
4262
4263
<p>(This corrects a bug that used to occur.  In the past, the library
4264
attempted to let the NPC respond, rather than generating a parser
4265
error.  The problem with this approach was that the soundproof barrier
4266
stopped the PC from hearing the NPC's response, thus the library could
4267
only report that "Nothing obvious happens."  Now that this is handled
4268
as a parsing error instead of a conversational response, the more
4269
helpful "Bob does not appear to hear you" is displayed.)
4270
4271
</div>
4272
4273
<!------------------->
4274
<div class=entry>
4275
4276
Thing.isListedInRoomPart has changed slightly.  In the past, an object
4277
was listed (i.e., shown in a miscellaneous list of portable contents)
4278
as part of an EXAMINE FLOOR (or EAST WALL or the like) if the object
4279
was nominally part of the room part (that is, nominally on the floor,
4280
or on the given wall, etc) <b>and</b> the object was normally listed
4281
the same way in a LOOK AROUND command.  Now, the object is listed if
4282
it's nominally part of the room part <b>and</b> the new RoomPart
4283
method isObjListedInRoomPart() returns true.
4284
4285
<p>The new method RoomPart.isObjListedInRoomPart returns true by
4286
default if the object does <b>not</b> have a special description for
4287
the purposes of examining the room part - that is, if the object's
4288
useSpecialDescInRoomPart returns nil.  We don't want to include the
4289
object in the miscellaneous list if it has a special description
4290
because the special description will be automatically shown - it would
4291
thus be mentioned twice if we included it in the miscellaneous list as
4292
well.
4293
4294
<p>Floor overrides isObjListedInRoomPart to list an object only if
4295
it's listed normally - that is, the object's isListed returns true.
4296
This is the old behavior that applied to <b>all</b> room parts, but
4297
now it only applies to Floor objects.  The reason we treat Floor
4298
differently is that everything that's directly in a room is by default
4299
nominally on the floor in the room, so if we didn't limit the listings
4300
like this in the case of EXAMINE FLOOR, we'd include all of the
4301
internal fixtures and components of the room, which is generally
4302
undesirable.
4303
4304
<p>The main purpose of this change is that it makes it a little easier
4305
to set up Fixture-type objects that are described as being situated on
4306
walls, ceilings, and the like.  Now, all that's necessary is to give
4307
the object a specialNominalRoomPartLocation - even if the object isn't
4308
normally listed in a room description, as is the case for a Fixture,
4309
we'll now list the object when we examine its room part as long as it
4310
doesn't have an explicit special description for the room part.
4311
4312
</div>
4313
4314
<!------------------->
4315
<div class=entry>
4316
4317
The new mix-in class RoomPartItem can be used to create an object that
4318
shows its special description when an associated room part is
4319
described.  This is useful for things like doors, windows, ceiling
4320
fans, and other objects attached to the room.  The main thing this
4321
class does is to make the object show its special description when its
4322
associated room part is examined (as in LOOK AT EAST WALL), but
4323
<i>not</i> in the main room description (as in LOOK AROUND).  This is
4324
desirable because this kind of object is usually not remarkable enough
4325
to call out with a special description in the overall room, but does
4326
warrant a mention when its associated room part is explicitly
4327
examined.
4328
4329
</div>
4330
4331
<!------------------->
4332
<div class=entry>
4333
4334
SensoryEmanation has a new property, isEmanating, that lets you turn
4335
the object on and off.  By default, is Emanating is true; if you set
4336
this to nil, it shuts off the emanation.  This makes it easier to make
4337
sounds and odors start and stop, which is often useful when the
4338
emanations are associated with dynamic objects such as actors.
4339
4340
</div>
4341
4342
<!------------------->
4343
<div class=entry>
4344
4345
Settable has a new method, canonicalizeSetting(), that converts a
4346
proposed new setting to a "canonical" format.  Settable now uses this
4347
to process the player's input before passing the value to
4348
isValidSetting() or makeSetting(), ensuring that these routines don't
4349
need to perform any further format conversion of their own.
4350
4351
<p>This method makes it much easier to handle superficial formatting
4352
variations in the player's input by centralizing the conversions to
4353
this single routine.  In the past, both isValidSetting() and
4354
makeSetting() had to handle formatting variations since they received
4355
the raw player input.
4356
4357
<p>Settable's default implementation of canonicalizeSetting() doesn't
4358
do anything - it just returns the original player input unchanged.
4359
NumberedDial overrides the method to convert spelled-out numbers to
4360
numeral format and to strip off any leading zeroes from an entered
4361
numeral format; LabeledDial overrides it to convert the input to the
4362
exact case of the matching entry in the list of valid labels.
4363
4364
</div>
4365
4366
<!------------------->
4367
<div class=entry>
4368
4369
The new library routines parseInt() and parseIntTokens() parse a
4370
string or token list (respectively) that contains a spelled-out or
4371
digit-string numeric value.  These routines parse the input and return
4372
the corresponding integer value, or nil if the input can't be parsed
4373
as a number.  For example, parseInt('one thousand and twenty-four')
4374
returns 1024, parseInt('72') returns 72, and parseInt('dusty tome')
4375
returns nil.
4376
4377
</div>
4378
4379
<!------------------->
4380
<div class=entry>
4381
4382
The English library now incorporates Michel Nizette's Past Tense
4383
extension.  This enables the author to select the tense - present or
4384
past - used in library messages, and even allows you to change the
4385
tense dynamically during the game.
4386
4387
<p>The 'master switch" for the active tense is gameMain.usePastTense.
4388
Set this to true to activate past tense in library messages.  The
4389
default is nil, which selects present tense.
4390
4391
<p>A number of new message parameters and verbEndingXxx properties
4392
help in writing messages that can change tense.  The standard library
4393
messages defined in en_us/msg_neu.t use these new features to adapt
4394
automatically to the current tense.
4395
4396
<p>See the comments in en_us/en_us.t for full details.
4397
4398
</div>
4399
4400
<!------------------->
4401
<div class=entry>
4402
4403
The library has a new framework for "global defaults," which lets the
4404
user save certain preference settings as default values for future
4405
sessions.  These saved defaults are global: they apply to <i>any</i>
4406
new game subsequently loaded, provided that the new game supports the
4407
new global defaults system.  Games compiled with library versions
4408
prior to 3.0.9 didn't support this new system, but games compiled with
4409
3.0.9 or later will support it by default, as long as an author
4410
doesn't explicitly disable it for some reason.  The settings are saved
4411
to a file whose name and location are determined by the interpreter
4412
(and which might vary by system, to conform to local conventions).
4413
4414
<p>Two new commands let the user control the global defaults: SAVE
4415
DEFAULTS saves the current settings to the configuration file, and
4416
RESTORE DEFAULTS explicitly loads the file and applies its settings.
4417
These commands both list the full set of saved settings, so that the
4418
user can easily tell exactly which settings are affected.
4419
4420
<p>By default, the library uses the new global settings framework
4421
for the VERBOSE, FOOTNOTES, NOTIFY, and EXITS settings.
4422
4423
<p>The new mechanism is implemented mostly in the new file settings.t.
4424
The main API is exposed through the new settingsManager object, and
4425
the command-line user interface is implemented in the new settingsUI
4426
object.  The new SettingsItem class is used to encapsulate individual
4427
configuration variables.  If you want to create your own extensions to
4428
the set of global default variables, simply create a SettingsItem
4429
object for each new variable you want to add.  The settings framework
4430
will automatically find your new SettingsItem objects, and save and
4431
restore them as needed.
4432
4433
</div>
4434
4435
<!------------------->
4436
<div class=entry>
4437
4438
The new macro gSetSeen(obj) marks an object as having been seen by the
4439
player character.
4440
4441
</div>
4442
4443
<!------------------->
4444
<div class=entry>
4445
4446
The new macro gTopicText returns a string containing the literal text
4447
of the current topic phrase, when the current action contains a topic
4448
phrase.  The text returned is as the user typed it, but converted to
4449
lower case.
4450
4451
</div>
4452
4453
<!------------------->
4454
<div class=entry>
4455
4456
The LiteralAction and LiteralTAction class are now based on a new
4457
common mix-in base class, LiteralActionBase.  This is parallel to the
4458
structure of TopicAction and TopicTAction, with their common mix-in
4459
base class TopicActionBase.  This new arrangement shouldn't at all
4460
change the behavior of LiteralAction or LiteralTAction, and should be
4461
entirely transparent to existing code.
4462
4463
<p>The change has two main benefits.  First, it eliminates some code
4464
duplication, by replacing a few bits of code that were effectively
4465
duplicated in LiteralAction and LiteralTAction with common versions
4466
that both classes now inherit from LiteralActionBase.  Second, game
4467
code can now easily determine if an action involves any sort of
4468
literal phrase, by testing gAction.ofKind(LiteralActionBase).
4469
4470
</div>
4471
4472
<!------------------->
4473
<div class=entry>
4474
4475
The new Thing method failCheck() makes it a little more convenient to
4476
write check() routines.  check() routines frequently use this pattern:
4477
4478
<p><pre>
4479
   check()
4480
   {
4481
     if (condition)
4482
     {
4483
       reportFailure('You can\'t do that for some reason.');
4484
       exit;
4485
     }
4486
   }
4487
</pre>
4488
4489
<p>The failCheck() routine encapsulates the display of the failure
4490
report and the termination of the action with 'exit'.  Using
4491
failCheck(), you can rewrite the code above more concisely,
4492
like so:
4493
4494
<p><pre>
4495
   check()
4496
   {
4497
     if (condition)
4498
       failCheck('You can\'t do that for some reason.');
4499
   }
4500
</pre>
4501
4502
</div>
4503
4504
<!------------------->
4505
<div class=entry>
4506
4507
Occluder.occludeObj() has a new default implementation.  By default,
4508
the method now asks the object being tested for occlusion to make the
4509
decision, by calling the object's isOccludedBy() method.
4510
4511
<p>Thing provides a default implementation of the new isOccludedBy()
4512
method, which simply returns nil to indicate that the object is not
4513
occluded by the given Occluder.
4514
4515
<p>Existing code won't be affected by this change, since any existing
4516
Occluder code already overrides isOccludedBy() to make the per-object
4517
occlusion decision.  The reason for this change is that it's sometimes
4518
easier to decide about occlusion in the individual objects rather than
4519
in the Occluder; the new default Occluder.occludeObj() makes it easer
4520
to write the code that way by providing a pre-defined framework that
4521
already works that way.
4522
4523
</div>
4524
4525
<!------------------->
4526
<div class=entry>
4527
4528
In the past, if a Container was used as the indirect object of PUT IN
4529
or POUR INTO, the library applied an objOpen precondition to ensure
4530
the container was open.  The library now applies the objOpen condition
4531
only if the actor performing the action isn't itself inside the
4532
container.  The reason for the objOpen condition is that putting or
4533
pouring things into a container requires access to the container's
4534
interior, and a container's interior is only reachable from outside
4535
the container when the container is open.  However, when an actor is
4536
inside a container, the actor can reach the inside of the container
4537
whether or not the container is open, so there's no need for the
4538
objOpen condition.
4539
4540
</div>
4541
4542
<!------------------->
4543
<div class=entry>
4544
4545
Fixture, Component, and Immovable now define custom handlers for PUT
4546
BEHIND that are consistent with their handlers for PUT IN, PUT ON, and
4547
PUT UNDER.
4548
4549
</div>
4550
4551
<!------------------->
4552
<div class=entry>
4553
4554
On an actor's attempt to take an item that was inside something the
4555
actor was already carrying, Actor.tryMakingRoomToHold() formerly
4556
double-counted the item's weight in enforcing the actor's carrying
4557
limit - it counted the item first for the weight of carrying the new
4558
item itself, then again for its contribution to the weight of its old
4559
container (because the old container was in the actor's inventory).
4560
The routine now correctly counts the weight only once.  (The new
4561
algorithm uses the whatIfHeldBy() method, which actually tests the
4562
proposed new arrangement to calculate the new weight carried and thus
4563
yields reliable results no matter what configuration previously
4564
existed.)
4565
4566
</div>
4567
4568
<!------------------->
4569
<div class=entry>
4570
4571
TAKE ALL now tries to take everything that's directly in the actor's
4572
current "drop destination", <i>or</i> that's directly in the actor's
4573
direct container, <i>or</i> that's in any intermediate container
4574
between the two.  The former behavior was to take everything in the
4575
actor's direct location only.  This change improves the behavior when
4576
the actor is in something like a chair or bed.  In these sorts of
4577
nested rooms, items dropped usually land in the enclosing room; the
4578
new behavior ensures that a TAKE ALL command attempted while in such a
4579
location will include items that were just dropped while in the same
4580
location.  With the former behavior in this situation, TAKE ALL missed
4581
the items in the drop location, which was likely to confuse players.
4582
4583
</div>
4584
4585
<!------------------->
4586
<div class=entry>
4587
4588
NonPortable now defines a default weight and bulk of zero.  Since
4589
these objects aren't meant to be carried or moved around by actors,
4590
their weight and bulk are essentially irrelevant; but the previous
4591
non-zero defaults occasionally had undesirable side effects in
4592
cases where a non-portable was a component of another object or
4593
among another object's contents.
4594
4595
</div>
4596
4597
<!------------------->
4598
<div class=entry>
4599
4600
An attempt to give an object to an NPC when the NPC is already holding
4601
the object in question is now ruled out as illogical ("Bob already has
4602
that").
4603
4604
</div>
4605
4606
<!------------------->
4607
<div class=entry>
4608
4609
The library now provides commands that let the player control the
4610
display of the exits listing in the status line.  EXITS ON now turns
4611
on <i>both</i> the status line and room description exit listings, and
4612
EXITS OFF turns them both off.  The new command EXITS STATUS (which
4613
can also be entered as EXITS STATUSLINE or EXITS STATUS LINE) turns on
4614
the status line exit listing only, and EXITS LOOK turns on the room
4615
description exit listing only.
4616
4617
<p>In addition, these new commands are now described in the standard
4618
instructions.
4619
4620
</div>
4621
4622
<!------------------->
4623
<div class=entry>
4624
4625
The "probabilistic firing" feature of the RandomEventList class is now
4626
available in a separate mix-in class, RandomFiringScript.  This new
4627
class can be mixed into the superclass list of any Script subclass to
4628
add the random firing feature.
4629
4630
<p>RandomEventList and ShuffledEventList are now based on the new
4631
RandomFiringScript.  This doesn't change their behavior; existing
4632
code based on these classes should continue to work unchanged.
4633
4634
</div>
4635
4636
<!------------------->
4637
<div class=entry>
4638
4639
The SyncEventList class now delegates calls to its scriptDone() method
4640
to its master list object.  This ensures that any explicit calls to a
4641
SyncEventList's scriptDone() method will be handled via the master
4642
list, which is consistent with SyncEventList's handling for most of
4643
its other methods.
4644
4645
</div>
4646
4647
<!------------------->
4648
<div class=entry>
4649
4650
The library now has a better response to the FOLLOW command if the
4651
target NPC departed the player character's present location while the
4652
PC was somewhere else.  Suppose the PC sees Bob in the living room,
4653
then goes to the dining room; while the PC is in the dining room, Bob
4654
departs for a third room (due to some scripted activity).  The player
4655
then returns to the living room.  At this point, it's not possible to
4656
FOLLOW BOB, since the PC didn't see where Bob went.  This much hasn't
4657
changed; what's changed is the library's default response if player
4658
types FOLLOW BOB in this situation.  In the past, the response was
4659
"The last place him was the living room," which is true but not very
4660
helpful (and a little non sequiturish).  Now, the response is "You're
4661
not sure where he went from here."
4662
4663
</div>
4664
4665
<!------------------->
4666
<div class=entry>
4667
4668
NominalPlatform now returns its location's effectiveFollowLocation as
4669
its own effectiveFollowLocation.  A nominal platform isn't meant to be
4670
part of the visible structure of the game world, so, for FOLLOW
4671
purposes, a character on a nominal platform is effectively in the
4672
enclosing room as far as the other characters in the room are
4673
concerned.
4674
4675
</div>
4676
4677
<!------------------->
4678
<div class=entry>
4679
4680
A bug in the parser caused possessive pronouns to be treated
4681
differently in a TopicTAction when the direct object phrase was
4682
missing than when it was provided.  For example, ASK BOB ABOUT HIS KEY
4683
was treated differently from the abbreviated equivalent A HIS KEY.
4684
This has been corrected.
4685
4686
</div>
4687
4688
<!------------------->
4689
<div class=entry>
4690
4691
The parser now drops its preference for untruncated name matches when
4692
resolving an object in "global scope," and instead treats truncated
4693
and exact name matches on an equal footing in these cases.  This
4694
change is analogous to the global scope changes for plurals and
4695
adjective-ending phrases introduced in 3.0.6q and 3.0.6p.  See the <a
4696
href='#global_scope_noun_adj'>adjective-ending notes</a> from 3.0.6p
4697
for details on what global scope is and why its rules on matching are
4698
more lenient.
4699
4700
<p>The practical effect of this change is that topic words will now
4701
match properly even when there are longer and shorter versions of the
4702
same vocabulary defined for various objects.  In the past, if one
4703
object was defined with a six-letter noun, and another object had a
4704
seven-letter noun with the same first six letters as the other object
4705
("coffee" and "coffees", say), the parser filtered out the
4706
seven-letter match in favor of the six-letter match, even though both
4707
objects ought to be equally valid in global scope.  With the change,
4708
both objects are now properly kept as possible resolutions when
4709
parsing a topic phrase.
4710
4711
</div>
4712
4713
<!------------------->
4714
<div class=entry>
4715
4716
The parser now selects Collective objects instead of their
4717
corresponding individuals when matching "all" and "all except
4718
<i>list</i>" noun phrases.
4719
4720
<p>Whether it's better to select the Collective or the individuals
4721
probably varies according to context, since the "right" one is the one
4722
the player intends in a particular command, and that will likely vary
4723
from one command to the next (and from one player to the next).  But
4724
the design of the parser requires that we choose one interpretation or
4725
the other across the board; context sensitivity isn't an option.  Even
4726
if context sensitivity were an option, we might still not have enough
4727
information to correctly read the player's mind every time.  This
4728
change - matching the Collective object instead of the individuals -
4729
seems more likely to yield intuitive results more of the time than the
4730
old behavior.
4731
4732
</div>
4733
4734
<!------------------->
4735
<div class=entry>
4736
4737
The parser now applies the normal filterResolveList() filtering when
4738
resolving a target-actor phrase (such as the "bob" in "bob, go
4739
north"), the same as it does when resolving other kinds of noun
4740
phrases.  In the past, the parser omitted this filtering step for
4741
target actors, which didn't give objects like Unthings and Collectives
4742
a chance to do their special filtering.
4743
4744
</div>
4745
4746
<!------------------->
4747
<div class=entry>
4748
4749
When the player enters a command of the form TAKE ALL FROM
4750
<i>iobj</i>, the TakeFrom action now lets the indirect object
4751
determine what ALL means.  It does this via a new method,
4752
getAllForTakeFrom(scopeList).  Thing implements this method using
4753
almost the same behavior that TakeFrom used in the past: it returns a
4754
list of everything in scope that's directly inside 'self' and isn't a
4755
component of 'self'.  The old behavior simply returned everything in
4756
scope that was directly inside the indirect object.
4757
4758
<p>ComplexContainer overrides getAllForTakeFrom() to return everything
4759
that's in scope and that's directly in (a) the sub-container or
4760
sub-surface, if the object has either, or (b) the sub-rear-surface or
4761
sub-underside, if the object doesn't have a sub-container or
4762
sub-surface; and as with Thing's version, this list is then limited to
4763
objects that aren't components of their direct containers.  Note that
4764
if there's both a sub-surface <i>and</i> a sub-container, the method
4765
will return everything that's in <i>either</i> of these; and likewise
4766
with the sub-rear-surface and sub-underside.
4767
4768
<p>This change is designed primarily to improve the behavior for
4769
ComplexContainers, which wasn't ideal under the old mechanism, as it
4770
only returned the complex container's sub-components, which are
4771
internal implementation objects that are meant to be invisible to the
4772
player.  Clearly, in the case a complex container, it's the contents
4773
of the inner containers that are of interest in TAKE ALL FROM.  This
4774
change also makes it easier to customize the TAKE ALL FROM behavior
4775
for your own special containers, since it gives the container a chance
4776
to determine what ALL means in context.
4777
4778
<p>The grammar class VagueContainerNounPhraseProd, which matches
4779
locational phrases such as "all in box" and "the one in the box," also
4780
uses the new method to determine which objects are involved.  This
4781
provides the same improvement for commands such as LOOK AT EVERYTHING
4782
IN THE BOX when a complex container or other special container is
4783
involved.
4784
4785
</div>
4786
4787
<!------------------->
4788
<div class=entry>
4789
4790
The NounPhraseWithVocab method getVocabMatchList() now takes an extra
4791
parameter, specifying any extra flags that should be OR'd into the
4792
ResolveInfo flags for the items in the match list.  In the past, the
4793
version of the method in the adjective-phrase subclasses took the
4794
extra flags parameter, but the base class method didn't, which made it
4795
difficult to create classes for production types that could define
4796
grammars with either the adjective or noun subproductions.
4797
4798
</div>
4799
4800
<!------------------->
4801
<div class=entry>
4802
4803
In the past, if the player typed STAND while the PC was sitting or
4804
lying on an object derived from BasicPlatform, the library simply made
4805
the PC stand up, remaining on the platform.  In particular, the
4806
library didn't bother checking the allowedPostures property to see if
4807
the platform actually allowed the 'standing' posture; it simply
4808
assumed that standing was allowed on any platform.  This didn't easily
4809
allow for things like booths with limited headroom.  The
4810
makeStandingUp method of BasicPlatform now checks allowedPostures
4811
property, to make sure that 'standing' is listed.  If 'standing' isn't
4812
among the allowed postures, the makeStandingUp method now inherits the
4813
base class handling, which removes the actor from the nested room and
4814
sets the actor's posture to the default for the enclosing location.
4815
This will produce better results in most cases, since the natural
4816
implication of STAND UP when in a vertically confined space would be
4817
to remove oneself from the space.
4818
4819
</div>
4820
4821
<!------------------->
4822
<div class=entry>
4823
4824
It's now possible to control the order in which preconditions are
4825
executed, at the level of the individual preconditions.  The new
4826
PreCondition property preCondOrder gives the order of execution of a
4827
given precondition.  The default for most types of preconditions is
4828
100; for TouchObjCondition (and thus for touchObj), it's 200, which
4829
means that touchObj conditions will execute after other conditions by
4830
default.
4831
4832
<p>It's occasionally useful to be able to fine-tune precondition order
4833
because preconditions can sometimes interfere with one another.  This
4834
is particularly a problem with implied actions that require the actor
4835
to be in a particular posture or location, because many of the
4836
standard preconditions can move the actor around as a side effect.
4837
For example, a doorOpen condition could execute an implied STAND as
4838
part of its implied OPEN DOOR; if another precondition requires the
4839
actor being to be sitting, its effect would be undone if the doorOpen
4840
were executed second.  We can safely STAND and OPEN DOOR first, then
4841
SIT DOWN second, because we'll still satisfy the doorOpen condition
4842
even though we're no longer standing when we're done.
4843
4844
<p>In addition to the new preCondOrder ordering, the default ordering
4845
has changed for two-object verbs (those with direct and indirect
4846
objects).  By default, the direct object preconditions are now
4847
executed first, followed by the indirect preconditions; in the past
4848
this order was reversed.  This is only the default order - the
4849
preCondOrder takes precedence.  That is, the action builds a list
4850
consisting of the direct object preconditions followed by the indirect
4851
object preconditions, then sorts that list in ascending order of
4852
preCondOrder, preserving the existing relative order of objects with
4853
the same preCondOrder.
4854
4855
</div>
4856
4857
<!------------------->
4858
<div class=entry>
4859
4860
adv3.h now defines a couple of new templates for your convenience:
4861
4862
<p><pre>
4863
   SyncEventList template -&gt;masterObject inherited;
4864
   Hint template 'hintText' [referencedGoals]?
4865
</pre>
4866
4867
</div>
4868
4869
<!------------------->
4870
<div class=entry>
4871
4872
When an Unthing is used as a possessive or locational qualifier ("the
4873
key in the unthing" or "the unthing's key," for example), the parser
4874
now shows the Unthing's "not here" message.  In the past, the parser
4875
showed the same default messages for an Unthing as for any other
4876
object, using wording like "The unthing doesn't appear to have that"
4877
or "You see no key in the unthing."  This wording was incongruous for
4878
Unthings because an Unthing represents the absence of an object, and
4879
hence an Unthing can't "appear" to have or contain - or even not have
4880
or not contain - anything.  Showing the Unthing's "not here" message
4881
yields more sensible results.
4882
4883
</div>
4884
4885
<!------------------->
4886
<div class=entry>
4887
4888
An Unthing now responds to LISTEN and SMELL commands with the same
4889
message it uses for EXAMINE (by default, "You don't see that here").
4890
This applies even if the Unthing is distant or obscured.  (In the
4891
past, the inherited Decoration messages for these verbs were used.)
4892
4893
</div>
4894
4895
<!------------------->
4896
<div class=entry>
4897
4898
The English library provides a new template for Unthing:
4899
4900
<p><pre>
4901
Unthing template 'vocabWords' 'name' @location? 'notHereMsg'?;
4902
</pre>
4903
4904
</div>
4905
4906
<!------------------->
4907
<div class=entry>
4908
4909
The finishGame() function now updates the global turn counter to
4910
reflect any turn currently in progress, or, when called from a daemon
4911
or fuse, the turn the player has already completed.  In the past, the
4912
turn counter displayed in finishGame() didn't reflect the turn in
4913
progress that triggered the call to finishGame().  Internally, a turn
4914
isn't counted in the global turn counter until it's finished; but from
4915
the player's perspective, a turn should count as soon as it starts.
4916
This change ensures that the count that finishGame() displays is
4917
consistent with the player's expectations.
4918
4919
</div>
4920
4921
<!------------------->
4922
<div class=entry>
4923
4924
A Lockable that's also an Openable no longer reports its
4925
locked/unlocked status when the object is open.  By default, an
4926
Openable must be closed in order to be locked, so if it's open, it's
4927
always unlocked.  This means that the locked/unlocked status is
4928
effectively redundant information when the object is open.
4929
4930
<p>By way of implementation, the Lockable class has a new method,
4931
lockStatusReportable, that indicates whether or not the lock status is
4932
worth mentioning in the object's current state.  (This doesn't
4933
supersede lockStatusObvious, but rather complements it.
4934
lockStatusObvious still indicates whether or not the lock status is
4935
visually apparent; lockStatusReportable indicates whether it's worth
4936
mentioning from an aesthetic point of view.)  Lockable defers to any
4937
mix-in class that provides the method, and Openable takes advantage of
4938
this by providing an implementation of the method that returns true if
4939
the object is closed, nil if it's open.
4940
4941
</div>
4942
4943
<!------------------->
4944
<div class=entry>
4945
4946
Door and SecretDoor are now based on a new common base class,
4947
BasicDoor.  The new BasicDoor class defines the core internal behavior
4948
of a door: a travel connector object that can be open or closed, that
4949
allows travel only when open, and that can have two objects linked
4950
together to represent the two sides of the door.
4951
4952
<p>The relationship between BasicDoor and Door is analogous to that
4953
between BasicOpenable and Openable.  BasicDoor defines the internal
4954
behavior, while Door adds handling for user commands to manipulate the
4955
door (in particular, OPEN, CLOSE, LOCK, UNLOCK).
4956
4957
<p>This change doesn't affect the functionality of Door; it merely
4958
rearranges the code for Door internally by moving a few methods to the
4959
new BasicDoor base class.  SecretDoor isn't much affected, either, but
4960
does now add support for remembering a recent traversal for
4961
disambiguation purposes, as Door did in the past (and still does).  No
4962
changes should be needed in existing game code.
4963
4964
<p>The main benefits of this change are that it makes SecretDoor
4965
behave more consistently with the Door class, and it provides a single
4966
base class for all door-like objects.  In addition, the new BasicDoor
4967
class makes it easier to define custom doors with special controls,
4968
since it has all of the necessary functionality but doesn't make any
4969
assumptions about handling commands.
4970
4971
</div>
4972
4973
<!------------------->
4974
<div class=entry>
4975
4976
BasicDoor.noteRemoteOpen() now calls a new method,
4977
describeRemoteOpen(), to generate the message describing the change.
4978
This makes it easier to override the message for a door, since you can
4979
simply display the custom message without having to worry about the
4980
sense context.
4981
4982
</div>
4983
4984
<!------------------->
4985
<div class=entry>
4986
4987
The Enterable and Exitable classes no longer accept the GO THROUGH
4988
command.  In the past, these classes did accept GO THROUGH as
4989
synonymous with travel, but this became undesirable when the
4990
EntryPortal and ExitPortal classes were added.  Enterable and Exitable
4991
are meant for things like buildings, where ENTER or EXIT make sense
4992
but not GO THROUGH; EntryPortal and ExitPortal are for things like
4993
doors and passages, where you can equally well ENTER/EXIT them or GO
4994
THROUGH them.
4995
4996
</div>
4997
4998
<!------------------->
4999
<div class=entry>
5000
5001
The AutoClosingDoor class has a new method, reportAutoClose(), that
5002
generates the message that mentions that the door closed behind
5003
whoever just went through it.  The TravelVia action() handler calls
5004
reportAutoClose() after it automatically closes the door; by default,
5005
reportAutoClose() shows the standard library message
5006
&amp;doorClosesBehindMsg.  In the past, the action() handler simply
5007
showed the same library message itself, rather than calling out to a
5008
separate method.
5009
5010
<p>The purpose of this change is to make it easier to customize how
5011
the auto-closing is reported, or whether it's reported at all.  If
5012
you want the door to close silently, without any mention that it
5013
closed, simply override reportAutoClose() to do nothing.
5014
5015
</div>
5016
5017
<!------------------->
5018
<div class=entry>
5019
5020
By default, a FireSource object now removes itself from consideration
5021
as a default indirect object for the BurnWith action if it's not
5022
already lit.  This ensures that the library won't (for example)
5023
attempt to use an unlit candle as a default source of fire to light
5024
another candle.  In the past, under certain circumstances, the library
5025
could cause a stack overflow by trying to light one candle with
5026
another, which it tried to light with the first, and so on.  This
5027
change ensures that a fire source will only be chosen as the default
5028
indirect object for BurnWith if it's already lit.
5029
5030
<p>(Matchstick objects, of course, aren't affected by this change,
5031
since they can light themselves on fire independently.  Matchsticks
5032
thus remain valid as default choices for BurnWith even when they're
5033
unlit.)
5034
5035
</div>
5036
5037
<!------------------->
5038
<div class=entry>
5039
5040
The Wearable class now sets an elevated likelihood (via logicalRank())
5041
for a REMOVE (or TAKE OFF or DOFF) command when the object is being
5042
worn.  This helps avoid disambiguation prompts for these commands.
5043
5044
</div>
5045
5046
<!------------------->
5047
<div class=entry>
5048
5049
When a Hidden object is discovered (via its 'discover()' method), the
5050
object now marks itself and its contents as having been seen by the
5051
player character, assuming they're within sight at the time the object
5052
is discovered.
5053
5054
</div>
5055
5056
<!------------------->
5057
<div class=entry>
5058
5059
The new RoomPart methods moveIntoAdd(room) and moveOutOf(room) make it
5060
easier to dynamically change a room's set of RoomPart objects.  In the
5061
past, there was no straightforward way to change a room's RoomParts
5062
dynamically; these new methods make it easy by making the necessary
5063
updates to the affected room's properties.
5064
5065
</div>
5066
5067
<!------------------->
5068
<div class=entry>
5069
5070
Room.getExtraScopeItems() now adds the room's floor to scope only if
5071
the actor is directly in the room.  In the past, this routine added
5072
the floor to scope unconditionally.  The rationale of adding the floor
5073
to scope is that an actor standing in a room is aware that there's a
5074
floor there simply by virtue of standing on it - but that rationale
5075
only holds when the actor is actually standing on the floor (or
5076
sitting on it, or whatever), and that's only the case when the actor
5077
is actually directly in the room.  If the actor is in a connected
5078
room, or inside a nested room within the outer room, then in most
5079
cases the actor isn't actually in contact with the floor.
5080
5081
<p>Similarly, NestedRoom.getExtraScopeItems() now adds the nested room
5082
to scope only when the actor is directly in the nested room.  The
5083
rationale is the same as for the floor in an outer room.
5084
5085
</div>
5086
5087
<!------------------->
5088
<div class=entry>
5089
5090
The TALK TO command now treats talking to oneself as illogical; in
5091
the past, it was merely considered improbable.
5092
5093
<p>A side effect of this change is that the intransitive
5094
conversational commands (HELLO, GOODBYE, YES, NO) won't try to make
5095
the PC talk to itself by default.  In version 3.0.8, these commands
5096
were enhanced to choose the same default interlocutor as TALK TO would
5097
when the most recent interlocutor is no longer present.  This had the
5098
undesirable effect of choosing the PC as the default target when no
5099
other actors were present.  Now that TALK TO won't choose the PC as
5100
the default actor, HELLO and the rest won't do so, either.
5101
5102
</div>
5103
5104
<!------------------->
5105
<div class=entry>
5106
5107
In past versions, the InConversationState's "boredom counter" was
5108
handled inconsistently in certain cases.  In particular, when an NPC
5109
initiated a conversation, it took one more turn for the NPC to become
5110
bored than it took when the PC initiated the conversation.  This has
5111
been corrected.
5112
5113
</div>
5114
5115
<!------------------->
5116
<div class=entry>
5117
5118
The library now uses the "identity" object when setting a pronoun
5119
antecedent in Actor.setPronounObj().  This ensures that when an
5120
internal program object is being manipulated, and that object
5121
generates a pronoun antecedent, any subsequent command reference to
5122
the antecedent will properly refer to the main simulation object
5123
associated with the internal implementation object.  For example, this
5124
ensures that when a ComplexComponent is manipulated, subsequent
5125
references to "it" refer back to its ComplexContainer parent.
5126
5127
</div>
5128
5129
<!------------------->
5130
<div class=entry>
5131
5132
A library bug introduced in version 3.0.8 caused a run-time error when
5133
the player attempted to address a command to another actor and used a
5134
pronoun to identify the target actor (as in HIM, GO NORTH or ASK HIM
5135
TO GO NORTH - the first phrasing is awkward enough that most players
5136
wouldn't think to use it, but the ASK phrasing is natural enough that
5137
players might try it).  This has been corrected.
5138
5139
</div>
5140
5141
<!------------------->
5142
<div class=entry>
5143
5144
A bug in ThingOrTopicMatchTopic.isMatchPossible caused a run-time
5145
error under certain conditions.  This has been fixed.
5146
5147
</div>
5148
5149
<!------------------->
5150
<div class=entry>
5151
5152
The &lt;.roomname&gt; style tag now adds a newline after the room name
5153
text; this is in lieu of the &lt;.roomdesc&gt; style tag showing a
5154
newline before the room description, as was done in the past.  The
5155
newline is really part of the room name formatting, to ensure that the
5156
room name goes on a line by itself.  This change won't affect most
5157
existing games, since the usual LOOK AROUND format shows the room name
5158
followed by the long description; but the change does ensure that a
5159
room description won't have an extra leading newline in cases where
5160
the room name isn't displayed.
5161
5162
</div>
5163
5164
<!------------------->
5165
<div class=entry>
5166
5167
In Intangible, Fixture, Decoration, Room, and RoomPart,
5168
hideFromDefault() now simply returns nil.  (In the past, these classes
5169
defined hideFromDefault() as returning the inherited value, which
5170
didn't have the desired effect of bypassing the inherited call (from
5171
Thing.hideFromDefault()) to self.hideFromAll().  These classes
5172
override hideFromAll(), but they want to use separate handling for
5173
hideFromDefault().  The old override didn't correctly accomplish this
5174
because of the way the base Thing implementation of hideFromDefault()
5175
is written.)
5176
5177
</div>
5178
5179
<!------------------->
5180
<div class=entry>
5181
5182
The library now responds to commands like THROW ME, THROW ME AT
5183
<i>something</i>, and THROW ME TO <i>something</i> with an appropriate
5184
failure message.  (In the past, these commands were actually allowed,
5185
and used the standard THROW handling, which obviously isn't
5186
desirable.)
5187
5188
</div>
5189
5190
<!------------------->
5191
<div class=entry>
5192
5193
The library now accepts SIT and LIE (and, equivalently, SIT DOWN and
5194
LIE DOWN) as intransitive verbs.  In the past, these were defined as
5195
missing-direct-object forms of the transitive commands SIT ON and LIE
5196
ON, which meant that the library tried to find a default direct
5197
object.  This had the undesirable effect of making an actor who was
5198
already sitting/lying automatically stand up and sit/lie on some other
5199
suitable object in the room, which as a last resort was the default
5200
floor.  The new intransitive verbs check to see if the actor is
5201
already sitting/lying, and if so, simply generate an error message to
5202
this effect.  If the actor isn't already sitting/lying, the new
5203
commands proceed as before: they look for a suitable default object,
5204
and sit/lie on that.
5205
5206
<p>As part of this change, the intransitive SIT DOWN and LIE DOWN
5207
phrasings no longer have [badness], so the parser will match them
5208
as full-fledged intransitive phrasings.
5209
5210
</div>
5211
5212
<!------------------->
5213
<div class=entry>
5214
5215
There are two small changes to the action message processor.
5216
5217
<p>First, it's now possible to define a message method on a Thing that
5218
takes no arguments, even if the message normally does require
5219
arguments.  This makes it more syntactically convenient to define
5220
simple message string or property-redirect methods that require some
5221
small chunk of code, but which don't need any of the argument values
5222
that are normally sent to the message method.  For example, we can now
5223
write this:
5224
5225
<p><pre>
5226
   notImportantMsg = (myGenericMsg)
5227
</pre>
5228
5229
<p>instead of this (which was formerly required):
5230
5231
<p><pre>
5232
   notImportantMsg(obj) { return myGenericMsg; }
5233
</pre>
5234
5235
<p>Second, these sorts of message methods can now return nil to
5236
indicate that they don't want to provide the message after all.  This
5237
is useful when an object only wants to override a library message when
5238
it's in a certain state.  It's also useful when an object wants to
5239
provide the message only when that object is in a particular role in a
5240
two-object command (i.e., a command with both a direct and indirect
5241
object).  Recall that when a command involves both a direct and an
5242
indirect object, the message processor asks both of the objects for an
5243
override; this new capability lets the objects be selective about
5244
providing an override according to their actual roles in the command.
5245
5246
<p>For example, suppose you want your 'vase' object to override the
5247
"not a container" message for PUT IN, but only when the vase is the
5248
indirect object of the PUT IN, not when it's being put somewhere
5249
itself.  To do this, you could write vase.notAContainer like so:
5250
5251
<p><pre>
5252
   notAContainerMsg = (gIobj == self
5253
                       ? 'The vase\'s opening is too small.' : nil)
5254
</pre>
5255
5256
<p>The library provides a pair of new macros that simplifies the
5257
syntax for that kind of conditional message override:  dobjMsg()
5258
and iobjMsg().  These macros simply test to see if gDobj or gIobj
5259
(respectively) equal 'self'; if so, they return the argument, and
5260
if not they return nil.
5261
5262
</div>
5263
5264
<!------------------->
5265
<div class=entry>
5266
5267
The statusLine object has a new method, setColorScheme(), that sets up
5268
the status line's colors.  This change won't affect any existing code,
5269
since it's just a minor internal reorganization, and the behavior is
5270
the same as it used to be.  The point of the change is that it's now
5271
easier to customize the status line color scheme, since you only have
5272
to override this one method, and the only thing the override has to
5273
do is to write out a &lt;BODY&gt; tag with the desired color scheme.
5274
5275
</div>
5276
5277
<!------------------->
5278
<div class=entry>
5279
5280
The English tokenizer now recognizes upper-case "'S" (apostrophe-S)
5281
suffixes as equivalent to the lower-case version.  In the past, the
5282
tokenizer only recognized this token in lower-case.
5283
5284
</div>
5285
5286
<!------------------->
5287
<div class=entry>
5288
5289
In the English version, the SpecialTopic matcher now specifically
5290
rejects matches for several "weak" topic command inputs: I, L, and
5291
LOOK.  The matcher only rejects the matches when these are the
5292
<i>only</i> thing the player typed.  If the player types just "I", for
5293
example, they probably intend to enter an INVENTORY command rather
5294
than to select a special topic that happens to have "I" among its
5295
tokens (as in "tell him I don't know").
5296
5297
</div>
5298
5299
<!------------------->
5300
<div class=entry>
5301
5302
In the English grammar, plurals are now accepted as possessive
5303
qualifier phrases (as in "the women's books").  When a plural
5304
possessive is used to qualify a plural phrase ("the women's books"),
5305
the parser resolves the overall phrase to all of the in-scope objects
5306
matching the base noun phrase that are owned by anyone matching the
5307
qualifier phrase.  When a plural possessive qualifies a singular noun
5308
("the women's book"), the parser makes the same initial selection, but
5309
then prompts for more information if the selection includes more than
5310
one object.
5311
5312
</div>
5313
5314
<!------------------->
5315
<div class=entry>
5316
5317
When a possessive phrase is used to qualify a noun phrase, and the
5318
result is ambiguous, the parser now filters the list of possible
5319
matches using the filterResolveList() mechanism.  This ensures that
5320
special objects - especially Unthings and Collectives - are treated
5321
the same in this case as they are in other situations.  In the past,
5322
for example, the parser included Unthings in a disambiguation list if
5323
the Unthings matched the vocabulary of a possessive qualifier; this
5324
was undesirable because Unthings aren't meant to be treated as actual,
5325
present objects from the player character's perspective.
5326
5327
</div>
5328
5329
<!------------------->
5330
<div class=entry>
5331
5332
In the past, if the player responded to a disambiguation prompt with a
5333
possessive phrase, and the specified possessor didn't own any of the
5334
objects in the original disambiguation list, the parser responded with
5335
a message like "Bob does not appear to have any such thing."  This was
5336
inconsistent with the way disambiguation responses are treated for
5337
other types of responses.  Now, an inappropriate possessive response
5338
receives the same message as would a random adjective that doesn't
5339
apply to any of the original possibilities: "That was not one of the
5340
choices."
5341
5342
</div>
5343
5344
<!------------------->
5345
<div class=entry>
5346
5347
The English version of the library now lets the Action determine which
5348
message to use when there's nothing in scope matching a noun phrase in
5349
a command.  In the past, the parser always used the "noMatch" message,
5350
the default wording of which was "You see no <i>noun phrase</i> here."
5351
This was sometimes jarring for commands that generally refer to
5352
non-visual objects, such as LISTEN TO or SMELL.  With this change, the
5353
library now calls the Action (via its new method noMatch()) to
5354
determine which message to show.  Most actions simply invoke the new
5355
message method noMatchCannotSee(), which shows the same message as
5356
before.  The LISTEN and SMELL actions override noMatch() to call the
5357
new message method noMatchNowAware(), which shows the message "You are
5358
not aware of any <i>noun phrase</i> here."  The new wording should be
5359
more natural when the noun phrase is something inherently non-visual.
5360
5361
<p>(It would be even better if the library could decide based on the
5362
noun phrase itself whether the noun phrase refers to something visual
5363
or not, since the player could just as well try to EXAMINE THE
5364
SULFUROUS ODOR or TAKE THE BEEPING NOISE.  Unfortunately, it's
5365
effectively impossible to do this, since the true meaning of the error
5366
message is that the parser can't determine what the noun phrase
5367
actually refers to.  We don't want to say that outright, of course,
5368
since that would detract from the player's sense of immersion in the
5369
game world by calling attention to the parser and its limitations, so
5370
the best we can do is to find a heuristic that works most of the time.
5371
The addition of the per-action customization improves on the old
5372
scheme and should make incongruous cases relatively rare.)
5373
5374
</div>
5375
5376
<!------------------->
5377
<div class=entry>
5378
5379
The parser's algorithm for choosing grammar matches has been
5380
fine-tuned to handle cases with truncated words and adjective-ending
5381
phrases a little better, particularly in commands involving multiple
5382
objects.  In some cases, when presented with a two-object command
5383
(e.g., PUT X IN Y) in which one of the object phrases failed to match
5384
any in-scope objects, for the <i>other</i> phrase, the parser formerly
5385
chose a noun-ending phrase over an adjective-ending phrase, even if
5386
the adjective-ending version matched an object in scope and the
5387
noun-ending version didn't.  This sometimes yielded odd "you don't see
5388
that" messages that named the object that actually <i>was</i> in
5389
scope, from the player's perspective.  This change should improve
5390
the behavior in situations like this.
5391
5392
</div>
5393
5394
<!------------------->
5395
<div class=entry>
5396
5397
In the English library, the code that tries to figure out whether to
5398
use "a" and "an" for an object's aName now ignores any leading HTML
5399
tags in the object's base name.  This is useful for objects with
5400
aName strings such as "&lt;i&gt;Apple County Times&lt;/i&gt;".
5401
5402
<p>In addition, the code now specially recognizes names that start
5403
with one-letter words (such as "X-ray" or "&lt;q&gt;L&lt;/q&gt;
5404
button"), and assumes they're pronounced by saying the name of the
5405
letter.  So, for example, "X-ray" turns into "an X-ray," since the "X"
5406
is pronounced as "ex."
5407
5408
</div>
5409
5410
<!------------------->
5411
<div class=entry>
5412
5413
The English library now accepts SET as a synonym for PUT in the
5414
commands PUT DOWN, PUT ON, PUT IN, PUT UNDER, and PUT BEHIND.
5415
5416
<p>SET is also now accepted as a single-object verb.  When applied to
5417
a Thing, the library assumes the intention is SET <i>thing</i> ON
5418
<i>something</i>, and prompts for the other object.  When applied to a
5419
Settable, the library assumes the intention is SET <i>settable</i> TO
5420
<i>setting</i>, and prompts for the setting.
5421
5422
<p>Note that the single-object form (simply SET <i>dobj</i>) could be
5423
useful all by itself in some cases: SET ALARM, for example.  For such
5424
cases, you can simply define a custom dobjFor(Set) for the object.
5425
5426
</div>
5427
5428
<!------------------->
5429
<div class=entry>
5430
5431
In the English library, L is now accepted as a synonym for LOOK in the
5432
various forms of the LOOK UP and LOOK FOR commands: L UP topic IN
5433
object, L topic UP IN object, L FOR topic, etc.
5434
5435
</div>
5436
5437
<!------------------->
5438
<div class=entry>
5439
5440
In the English library, THROW <i>iobj</i> <i>dobj</i> is now accepted
5441
as a synonym for THROW <i>dobj</i> TO <i>iobj</i>, allowing phrasing
5442
like THROW BOB THE BALL.
5443
5444
<p>In addition, THROW <i>obj</i> <i>direction</i> (as in THROW BOOK
5445
EAST) is now accepted, via the new action ThrowDir.  The default
5446
handling for ThrowDir (in Thing) is simply to display a message
5447
essentially explaining that the proper command is THROW AT: "You need
5448
to be more specific about what you want to throw the book at."  If the
5449
phrasing is THROW <i>obj</i> DOWN or THROW DOWN <i>obj</i>, though, we
5450
use the same response we use for THROW AT FLOOR ("You should just put
5451
it down instead").
5452
5453
</div>
5454
5455
<!------------------->
5456
<div class=entry>
5457
5458
The parser's grammar ranking mechanism has a new ranking criterion:
5459
"phrasing weakness."  This is an arbitrary numeric value that the
5460
language module can use to rank particular phrasings as relatively
5461
weak, which means that they're less likely to be valid matches.
5462
5463
<p>The English grammar uses this new criterion to mark phrasings as
5464
weak when they involve two object phrases with no prepositional marker
5465
and no qualifier word - things like GIVE BOB BOOK.  These phrasings
5466
are weak because they could be interpreted as a single object with a
5467
missing phrase instead of two objects - if the wording were GIVE GREEN
5468
BOOK, for example, there's probably a GREEN BOOK and a missing object
5469
rather than two objects GREEN and BOOK.  A phrasing such as GIVE BOOK
5470
TO BOB isn't weak because the prespositional marker makes the grammar
5471
fairly unambiguous; likewise, GIVE BOB THE BOOK is relatively clear
5472
because the article "the" can't normally go in the middle of a noun
5473
phrase, so most likely introduces a second noun phrase.
5474
5475
</div>
5476
5477
<!------------------->
5478
<div class=entry>
5479
5480
In the English library, CLIMB UP and CLIMB DOWN without a direct
5481
object are now explicitly recognized in the grammar as missing-object
5482
versions of CLIMB UP <i>dobj</i> and CLIMB DOWN <i>dobj</i>.  This
5483
prevents the CLIMB <i>dobj</i> grammar from treating the UP or DOWN as
5484
a direct object, which usually yielded an ungainly response along the
5485
lines of "you see no up here."  (The missing-object CLIMB UP and CLIMB
5486
DOWN are marked with "badness" in the grammar, which means that if
5487
there actually is an in-scope object with vocabulary words "up" or
5488
"down", the CLIMB <i>dobj</i> form will still be matched - so CLIMB UP
5489
as short-hand for CLIMB THE UP STAIRWAY will continue to work as it
5490
did before.)
5491
5492
</div>
5493
5494
<!------------------->
5495
<div class=entry>
5496
5497
In the English library, the message substitution parameter "{a/he}"
5498
was incorrectly not marked as a sentence subject.  It's now so marked.
5499
5500
</div>
5501
5502
<!------------------->
5503
<div class=entry>
5504
5505
In the English library, the methods askMissingObject(),
5506
missingObject(), askMissingLiteral(), and missingLiteral() have been
5507
moved from class messageHelper (in en_us.t) to playerMessages (in
5508
msg_neu.t).  These methods are just message generators, so they belong
5509
in the message object with all of the other message generators.
5510
5511
</div>
5512
5513
<!------------------->
5514
<div class=entry>
5515
5516
In the English library, the messages for noMatchForAll have been
5517
changed to variations of "You see nothing suitable."  In the past, the
5518
message was "You see nothing to use for 'all' here," which was
5519
somewhat misleading: it suggested that there's nothing present at all,
5520
when the actual point is merely that there's nothing present that can
5521
be used in the manner specified.
5522
5523
</div>
5524
5525
<!------------------->
5526
<div class=entry>
5527
5528
In 3.0.8, OOPS X (for any literal X) was changed so that it didn't
5529
consume a turn, but OOPS (without a literal) was inadvertantly left
5530
unchanged, so it still counted as a turn.  This has been corrected: a
5531
bare OOPS command no longer consumes a turn.
5532
5533
</div>
5534
5535
<!------------------->
5536
<div class=entry>
5537
5538
In the past, if the player typed NOTE without any text for the note,
5539
the parser prompted for the missing text ("What do you want to
5540
note?").  It no longer does this.  Instead, the first time an empty
5541
NOTE is entered, the parser displays a message explaining that NOTE is
5542
usually used to enter a message, in case the player wasn't aware of
5543
that; and after that, the parser simply accepts an empty NOTE the same
5544
as any other.
5545
5546
</div>
5547
5548
<!------------------->
5549
<div class=entry>
5550
5551
In the past, typing the secret command XSPCLTOPIC by itself on a
5552
command line caused a run-time error.  (XSPCLTOPIC is a verb that the
5553
library uses internally to handle SpecialTopic entries.  It's not
5554
something the player ever needs to type, or indeed is ever allowed to
5555
type, but at certain time, the library internally runs XSPCLTOPIC
5556
commands through the normal command processing as though the player
5557
had typed.)  This has been fixed.
5558
5559
</div>
5560
5561
<!------------------->
5562
<div class=entry>
5563
5564
In the past, if the parser asked for a missing literal phrase (such as
5565
for TYPE), and the player responded with input that included a
5566
character that the game's tokenizer didn't accept, the game displayed
5567
an "unknown exception" message.  The problem was that the parser
5568
didn't properly catch the tokenizer's bad-token exception in this
5569
case.  The parser now catches this exception and reports it as normal.
5570
5571
</div>
5572
5573
<!------------------->
5574
<div class=entry>
5575
5576
In the English library, when the parser is announcing the name of each
5577
object in a multi-object command, paragraph breaks are now suppressed
5578
after the object name.  This slightly improves formatting in cases
5579
where the action response for an object happens to start with a
5580
paragraph break.
5581
5582
</div>
5583
5584
<!------------------->
5585
<div class=entry>
5586
5587
In the English library, the verb-phrase builder method (getVerbPhrase())
5588
for TopicAction, TopicTAction, LiteralAction, and LiteralTAction didn't
5589
work correctly.  This has been corrected.
5590
5591
</div>
5592
5593
<!------------------->
5594
<div class=entry>
5595
5596
The new output control pseudo-tag &lt;./P0&gt; cancels the effect
5597
of an immediately preceding &lt;.P0&gt; tag.  This is useful in
5598
certain cases where you want to ensure that a newline or paragraph
5599
break is displayed, even if a &lt;.P0&gt; was just displayed.
5600
5601
</div>
5602
5603
<!------------------->
5604
<div class=entry>
5605
5606
All of the various spellInt-related functions are now implemented in
5607
en_us.t.  Some of these functions were formerly in numbers.t, but that
5608
wasn't the right place for them because some language modules might
5609
need to change these functions' interfaces (for example, to specify
5610
the grammatical case or gender of the result).  This change should
5611
have no effect on any existing game code; it's a purely internal
5612
change.
5613
5614
</div>
5615
5616
<!------------------->
5617
<div class=entry>
5618
5619
The message property 'flashlightOnButDark' has been renamed to
5620
'flashlightOnButDarkMsg' (that is, the suffix 'Msg' has been added)
5621
for consistency with the other message property names.
5622
5623
</div>
5624
5625
<!------------------->
5626
<div class=entry>
5627
5628
The default library message for TASTE has been changed to "It tastes
5629
as you expected" (from "You taste nothing out of the ordinary").  This
5630
emphasizes that the physical action was completed but that nothing
5631
unusual was detected; the old message could have been read as
5632
suggesting that the object in question had no flavor at all, which
5633
obviously isn't true of most objects.
5634
5635
<p>In addition, UntakeableActor and Person now use messages similar to
5636
those used for TAKE ("The cat won't let you," "Bob probably wouldn't
5637
like that"), since these sorts of actors are meant to exhibit
5638
volition, and in the real world would generally not allow themselves
5639
to be arbitrarily tasted.
5640
5641
</div>
5642
5643
<!------------------->
5644
<div class=entry>
5645
5646
A couple of the default library messages for POUR incorrectly referred
5647
to the direct object where they meant to use the indirect object.
5648
These have been fixed.
5649
5650
</div>
5651
5652
<!------------------------------- 3.0.8 --------------------------------->
5653
<div class="sepbar"><a name='308'></a>3.0.8</div>
5654
<p><b><i>Released 9/12/2004</i></b>
5655
<p>
5656
5657
<div class=firstentry>
5658
5659
<b>Compatibility-breaking change:</b> The class formerly named
5660
ShipboardRoom has been renamed to simply Shipboard.  This name change
5661
is for consistency; most of the other similar mix-in classes are named
5662
as simple adjectives.  You should search your game code for any
5663
mentions of ShipboardRoom and change each to Shipboard.
5664
5665
<p>Note that the new class ShipboardRoom is provided for convenience
5666
as a pre-defined combination of Shipboard and Room.  This means that
5667
any rooms you previously defined with the superclass list
5668
<tt>ShipboardRoom, Room</tt> (and just changed, following the
5669
prescription above, to <tt>Shipboard, Room</tt>) can now be written
5670
simply as <tt>ShipboardRoom</tt>.  This is purely for convenience; you
5671
can leave the class list as <tt>Shipboard, Room</tt> and it will
5672
behave the same way.
5673
5674
</div>
5675
5676
<!------------------->
5677
<div class=firstentry>
5678
5679
<b>Compatibility-breaking change:</b> The class formerly named
5680
OccludingConnector is now called Occluder.  This change emphasizes
5681
that the class is a mix-in that isn't limited to use with sense
5682
connectors.
5683
5684
</div>
5685
5686
<!------------------->
5687
<div class=entry>
5688
5689
<b>Possibly compatibility-breaking change:</b> The parameters to the
5690
enterConversation() method of the ConversationReadyState class have
5691
changed.  The old second parameter, 'explicit', has been deleted and
5692
replaced with a new parameter, 'entry', which gives the TopicEntry (if
5693
any) that triggered the conversation entry.  Any game code that calls
5694
or overrides enterConversation() must be changed to accomodate the
5695
parameter change.
5696
5697
<p>The new parameter gives enterConversation() more information about
5698
what triggered the conversation.  This extra information is necessary
5699
because, without it, the conversation system wasn't able to properly
5700
handle topic entries that were marked as conversational but
5701
non-greeting (that is, the isConversational property is true, but
5702
impliesGreeting is nil).  In the past, such entries were incorrectly
5703
treated as though they were entirely non-conversational, so they
5704
didn't enter an in-conversation state when used in a response.
5705
5706
<p>Note that the same information conveyed by the old 'explicit'
5707
parameter can be inferred from the new 'entry' parameter.  When
5708
'entry' is nil, it means that the conversation entry is explicit,
5709
because it was triggered by a direct action (HELLO, etc.) rather than
5710
a TopicEntry.  When 'entry' is non-nil, it means that the conversation
5711
entry is implied by the TopicEntry.
5712
5713
</div>
5714
5715
<!------------------->
5716
<div class=entry>
5717
5718
<b>Possibly compatibility-breaking change:</b> The ConvNode method
5719
processSpecialCmd() has an additional parameter, as does the
5720
SpecialTopic method matchPreParse().  It's unlikely that any game code
5721
will be affected by this, because games don't normally override these
5722
methods - usually, games just define SpecialTopic keyword lists.
5723
5724
<p>The new parameter in both cases gives the "processed" version of
5725
the player's input.  The default SpecialTopic implementation now
5726
matches the processed version of the input rather than the original
5727
text the player entered.
5728
5729
<p>In the English library, the processed input is the player's
5730
original input with any periods, commas, question marks, exclamation
5731
marks, colons, and semicolons removed, and with any leading "A" or "T"
5732
keyword removed.
5733
5734
<p>The purpose of the change to the parameters of these methods is
5735
that it makes it simpler and more efficient to do this filtering.
5736
5737
<p>Note that the punctuation filtering is new.  We filter out the
5738
punctuation because it's not usually meaningful for matching special
5739
topics.  For example, if the player's input contains the correct
5740
keywords to match a special topic, we usually want to match the
5741
special topic even if the player (for example) put a period or
5742
question mark at the end of the command.
5743
5744
</div>
5745
5746
<!------------------->
5747
<div class=firstentry>
5748
5749
<b>Possibly compatibility-breaking change:</b> The format of the
5750
message generated by DropType.getReportPrefix() has been changed so
5751
that the message is expected to be a complete sentence.  This affects
5752
the library messages floorlessDropMsg, droppingObjMsg, throwHitMsg,
5753
and throwShortMsg (this last one is new in this update).  These
5754
methods and messages are mostly for internal use, but if you override
5755
or call DropType.getReportPrefix() in your code, or if you've
5756
customized any of these messages, you'll need to adjust your own
5757
messages for this change.
5758
5759
<p>The old sentence fragment format had a couple of problems.  First,
5760
it was likely to be problematic for some non-English translations.
5761
Second, it was less flexible than the new full-sentence format, even
5762
in English, for the purposes of adding new "drop type" objects and
5763
of adding new messages composed using the prefix.
5764
5765
</div>
5766
5767
<!------------------->
5768
<div class=entry>
5769
5770
The parser's pronoun antecedent rules have changed slightly.  In the
5771
past, when the player entered a command with multiple noun slots (such
5772
as UNLOCK DOOR WITH KEY), the parser always chose the last-resolved
5773
object as the antecedent for any future pronoun.  This meant that the
5774
parser remembered either the direct object or the indirect object,
5775
depending on the verb.  This rule didn't always produce the results
5776
that you'd expect in natural English conversation, and had the further
5777
drawback that the remembered object varied from verb to verb.
5778
5779
<p>The parser now remembers <i>both</i> objects for two-object verbs,
5780
and waits to make a decision until the player actually enters a
5781
command with a pronoun.  When the player types a singular pronoun (it,
5782
he, she), and the most recent command had multiple noun slots, the
5783
parser performs the standard "verify" evaluation on each potential
5784
antecedent and picks the most logical one.  If more than one
5785
antecedent is equally logical, the parser simply picks one arbitrarily,
5786
and announces the choice in the usual manner.  When the choice is
5787
completely arbitrary, it will always be the direct object of the
5788
two-noun command.
5789
5790
<p>Some examples:
5791
5792
<p>
5793
<pre>
5794
   &gt;LOCK DOOR WITH KEY
5795
   Locked.
5796
5797
   &gt;DROP IT
5798
   Dropped.   <i>(the key, because it's illogical to drop the door)</i>
5799
5800
   &gt;UNLOCK DOOR WITH KEY
5801
   (first taking the key)
5802
   Unlocked.
5803
5804
   &gt;OPEN IT
5805
   Opened.    <i>(the door, because it's illogical to open the key)</i>
5806
5807
   &gt;LOCK DOOR WITH KEY
5808
   (first closing the door)
5809
   Locked.
5810
5811
   &gt;EXAMINE IT
5812
   (the door)
5813
   It's a heavy wooden door.
5814
</pre>
5815
5816
<p>In the last command - EXAMINE IT - the choice of the two potential
5817
antecedents is arbitrary, because it's equally logical to examine the
5818
key or the door.  The parser thus chooses the direct object of the
5819
prior command, and announces the choice to alert the player (in case
5820
she was thinking "it" would refer to the key).
5821
5822
</div>
5823
5824
<!------------------->
5825
<div class=entry>
5826
5827
The new Thing method notifyMoveInto(newContainer) complements the
5828
existing moveInto notification routines notifyRemove() and
5829
notifyInsert().  The new notifyMoveInto() method is called last in the
5830
sequence, after notifyRemove() has been called on the old container
5831
tree and notifyInsert() on the new container tree.  notifyInsert()
5832
gives the object being moved a chance to perform any special
5833
additional processing before the move, or to veto the move (which it
5834
can do by displaying an explanatory message and calling 'exit', just
5835
as notifyRemove() and notifyInsert() are allowed to do).
5836
5837
<p>The new routine has several benefits.  First, it provides the
5838
object being moved with the same sort of notifications that the old
5839
and new containers already receive.  Since it runs along with these
5840
other notifications, it allows the same distinction as those other
5841
notifiers between moves that trigger these side effects (via calls to
5842
moveInto) and those that don't (via direct calls to baseMoveInto)
5843
Second, since the new method runs last, after the notifyRemove() and
5844
notifyInsert() notifications, it has the last chance to veto the move;
5845
this means that if it doesn't cancel the move, then the move will
5846
definitely proceed (at least to the extent that baseMoveInto() will be
5847
called).  Any side effects that must be carried out only when the move
5848
will succeed can thus be safely coded here.
5849
5850
</div>
5851
5852
<!------------------->
5853
<div class=entry>
5854
5855
The parser now provides more helpful error feedback when the player
5856
tries to enter a SpecialTopic command that's not active.
5857
5858
<p>First, the library automatically enters all of the keywords defined
5859
by special topics into the game's dictionary.  This ensures that the
5860
parser won't claim that special topic keywords are unknown if they're
5861
used out of context, as it did in the past.  It was confusing when the
5862
parser claimed that special topic keywords were unknown, because the
5863
parser most certainly did know them some of the time.
5864
5865
<p>Second, when the player enters a command that looks syntactically
5866
invalid, but which doesn't contain any unknown words, the parser scans
5867
recent special topics for a match.  If it finds a match, the parser
5868
will show a new message: "That command can't be used right now."  This
5869
old response - "The story doesn't understand that command" - was
5870
potentially confusing, since the story <i>can</i> recognize the exact
5871
same command at other times.
5872
5873
<p>The parser scans the list of special topics most recently listed in
5874
topic inventories, using the new specialTopicHistory object.  This
5875
object keeps track of a configurable number of the most recent
5876
SpecialTopic suggestions listed; set its maxEntries property, which
5877
defaults to 20, to the maximum number of recent entries to scan.  The
5878
purpose of the limit is to ensure that a scan won't take too long, by
5879
limiting the scan to the specified maximum number of SpecialTopic
5880
items.  The trade-off is that the parser will forget older
5881
suggestions, so they'll be met with the old "story doesn't understand"
5882
message if the player tries them.  However, it seems safe to assume
5883
that the player will also forget about older suggestions, and so won't
5884
think to try them.
5885
5886
<p>If you set maxEntries to nil, it essentially removes the limit to
5887
the number of entries to scan.  The library won't maintain the history
5888
list at all in this case.  Instead, to check an unrecognized command,
5889
the parser will simply scan <i>all</i> SpecialTopic objects in the
5890
entire game, whether or not they've ever been suggested in topic
5891
inventory displays.  This option might be preferable for a game where
5892
the total number of items is small enough that scanning them all
5893
doesn't take an appreciable amount of time.  (Or not.  Some authors
5894
might not want the parser to recognize previously-unseen special
5895
topics at all - even to the extent of saying "that command can't be
5896
used right now" - because doing so could conceivably give away
5897
upcoming plot developments.  That is, if the player accidentally types
5898
a command that happens to match a special topic that hasn't ever been
5899
suggested, the player could infer from the special error message that
5900
the command will do something later in the game.  The chances of
5901
actually giving away anything important this way seem rather remote,
5902
but this sort of thing rubs some authors the wrong way.  If you don't
5903
like the idea of using the different error message for special topics
5904
until after they've been suggested at least once, but you also don't
5905
want a limit on the number of past topics to remember, just set
5906
maxEntries to a very high number.)
5907
5908
</div>
5909
5910
<!------------------->
5911
<div class=entry>
5912
5913
The new property pluralOrder lets you control the order in which a set
5914
of objects is processed when the objects match a plural phrase in a
5915
command.  This property applies to all VocabObjects (which is the base
5916
class for any object with vocabulary words); the arbitrary default
5917
value is 100.
5918
5919
<p>In most cases, the order of processing for the matches for a plural
5920
phrase is arbitrary, so you won't need to worry about this new
5921
property.  Once in a while, though, it's convenient to be able to
5922
control the order of matching.  This is especially useful when objects
5923
have ordinal names (first door, second door, etc), or when objects are
5924
named by relative spatial position (top drawer, middle drawer, bottom
5925
drawer).
5926
5927
<p>Note that the new property only controls the order of processing
5928
within an individual plural phrase.  For example, in the command TAKE
5929
BOOKS AND MAGAZINES, the books will be sorted by their relative
5930
pluralOrder values, then the magazines will be sorted by theirs - but
5931
when the command is processed, all of the books will be taken before
5932
any of the magazines, regardless of the relative pluralOrder values.
5933
This is important because it ensures that commands are processed in
5934
the order specified by the player.
5935
5936
<p>Because pluralOrder and the existing disambigPromptOrder will
5937
probably be used in the same way most of the time, disambigPromptOrder
5938
now returns the pluralOrder value by default.  So, for the common case
5939
that the two properties should have the same value, you can simply set
5940
pluralOrder.
5941
5942
</div>
5943
5944
<!------------------->
5945
<div class=entry>
5946
5947
The new function cls() clears the screen, and takes care of a couple
5948
of chores that should always be done at the same time.  First, the
5949
function clears any text captured in the transcript manager, ensuring
5950
that text that was meant to be displayed before the screen was cleared
5951
won't show up on the new, blank screen.  Second, the function calls
5952
the new gameMain.setAboutBox() method after clearing the screen,
5953
ensuring that any &lt;ABOUTBOX&gt; tag is re-displayed; this is
5954
necessary because HTML TADS discards any old &lt;ABOUTBOX&gt;
5955
information whenever the screen is cleared.
5956
5957
</div>
5958
5959
<!------------------->
5960
<div class=entry>
5961
5962
The new method setAboutBox() has been added to the gameMain() object.
5963
This new method is designed as the place to put your game's
5964
&lt;ABOUTBOX&gt; tag, if you provide one.  The method is invoked
5965
during start-up, and is also called from the new cls() function,
5966
ensuring that the about-box information will be re-displayed each time
5967
the screen is cleared.
5968
5969
<p>The default implementation in GameMainDef does nothing.  The new
5970
method is simply a placeholder for the game's (optional) use.
5971
5972
<p>This change is designed to make it easier to manage your about-box
5973
information.  HTML TADS discards any previous &lt;ABOUTBOX&gt; tag
5974
when the screen is cleared, so it's necessary to re-display the tag
5975
whenever you clear the screen.  If you write your &lt;ABOUTBOX&gt; tag
5976
in the new gameMain.setAboutBox() method, and you always use the new
5977
cls() function to clear the screen (rather than calling the low-level
5978
clearScreen() function directly), the library will automatically keep
5979
yout about-box active.
5980
5981
</div>
5982
5983
<!------------------->
5984
<div class=entry>
5985
5986
You can now control whether or not a given verb accepts the word ALL
5987
in its noun phrases.  By default, every verb accepts ALL.  However, if
5988
you set the new gameMain property allVerbsAllowAll to nil, only the
5989
basic inventory-management verbs (TAKE, TAKE FROM, DROP, PUT IN, PUT
5990
ON) will accept ALL, and every other verb will simply show an error
5991
message ("'All' isn't allowed with that verb").
5992
5993
<p>Some authors like to limit usage of ALL to the basic inventory
5994
verbs, either because of tradition or because they think it's a sort
5995
of "cheating" when a player tries commands like OPEN ALL or EXAMINE
5996
ALL.  This feature is probably of particular interest to writers of
5997
puzzle-oriented games.
5998
5999
<p>In addition to the all-or-(almost-)nothing option setting in
6000
gameMain, you can control ALL acceptance on a verb-by-verb basis.  The
6001
new Action property actionAllowsAll controls whether a particular
6002
Action accepts ALL for its noun phrases.  By default, the base
6003
definition in Action simply returns the value of
6004
gameMain.allVerbsAllowAll.  In addition, the basic inventory verbs
6005
(Take, TakeFrom, Drop, PutIn, PutOn) override actionAllowsAll to
6006
return true.  If you want to enable or disable ALL for an individual
6007
action, you can use "modify" to set the property for that action
6008
class.
6009
6010
</div>
6011
6012
<!------------------->
6013
<div class=entry>
6014
6015
The library uses the new Style Tag &lt;.announceObj&gt; to set the
6016
display style for multi-object announcements.  (These are the little
6017
announcements, of the form "blue book:", that precede the responses
6018
when a command is applied to multiple objects.)
6019
6020
<p>The default display style is to show object announcements in bold
6021
text.  When a command operates on several objects, the response can
6022
get rather lengthy; the new bold-face style for the announcements is
6023
intended to make these responses easier to read by making the
6024
boundaries of the sub-parts more visually apparent.
6025
6026
<p>The new StyleTag object is called announceObjStyleTag.  You can use
6027
"modify" with this object to customize the announcement style, if you
6028
want.
6029
6030
</div>
6031
6032
<!------------------->
6033
<div class=entry>
6034
6035
Actor.lookAround(), Thing.lookAroundPov(), and Thing.lookAroundWithin()
6036
now accept a set of bit flags for the 'verbose' parameter.  'true' and
6037
'nil' can still be passed, and have the same meanings as before, so
6038
existing code doesn't need to be changed.  However, the new bit flags
6039
give you more control over the format of the listing.  The flags, which
6040
can be combined with the "|" operator, are:
6041
6042
<ul>
6043
<li>LookRoomName: include the room name, shown on a line by itself at
6044
the start of the description.
6045
<li>LookRoomDesc: show the full description of the room.
6046
<li>LookListSpecials: show the special descriptions (specialDesc) for
6047
visible objects that have them.
6048
<li>LookListPortables: list the portable items that are visible.
6049
</ul>
6050
6051
<p>Note that lookAroundWithin() <i>automatically</i> adds LookRoomDesc
6052
to the flags if the actor has never seen the room before.
6053
6054
<p>If you pass 'nil' for the 'verbose' parameter, the effect is the
6055
same as passing (LookRoomName | LookListSpecials | LookListPortables).
6056
If you pass 'true', the effect is the same as passing (LookRoomName |
6057
LookRoomDesc | LookListSpecials | LookListPortables).
6058
6059
<p>The main effect of this change is that it lets you generate a room
6060
description without including the room title, which wasn't possible in
6061
the past.  This can be useful for cases where the standard LOOK AROUND
6062
format isn't desirable, such as when describing the view through a
6063
sense connector to another room.
6064
6065
</div>
6066
6067
<!------------------->
6068
<div class=entry>
6069
6070
The new Thing method roomRemoteDesc(actor) lets you customize the way
6071
a room is described when it's viewed by an actor from another room.
6072
The library calls this from Thing.lookAroundWithin() when the actor
6073
who's viewing the room is not within the room being viewed.
6074
6075
<p>Note that none of the standard library commands ever call this new
6076
method, because the basic library doesn't provide any command to view
6077
a remote room.  However, games might provide their own commands to do
6078
so, such as LOOK THROUGH KEYHOLE, and you might want to call
6079
lookAroundWithin() to generate the descriptions in these cases.
6080
Doing so will invoke roomRemoteDesc instead of roomDesc to generate
6081
the room description.
6082
6083
<p>The default Thing.roomRemoteDesc implementation simply calls
6084
roomDesc.  You'll probably want to override this any time you actually
6085
use it, to show a suitable description from the remote actor's point
6086
of view.
6087
6088
</div>
6089
6090
<!------------------->
6091
<div class=entry>
6092
6093
A new Thing method, adjustLookAroundTable(), lets you customize the
6094
set of objects that lookAroundWithin() can mention.  By default, this
6095
routine removes the POV and actor objects (which are usually the same
6096
object) from the table, ensuring that these objects aren't mentioned.
6097
6098
<p>In the past, lookAroundWithin() simply removed the actor object
6099
directly, so the default behavior is the same as in the past. 
6100
Separating this out into a new method lets games customize which
6101
objects are mentioned and which aren't for the particular room and
6102
point of view.
6103
6104
</div>
6105
6106
<!------------------->
6107
<div class=entry>
6108
6109
The new Thing method isLookAroundCeiling() determines whether the LOOK
6110
AROUND description for a given object is generated by that object
6111
directly, or by its location.  By default, this routine returns true
6112
if either the object is a top-level room (that is, it has a nil
6113
location), <i>or</i> the object's enclosing location isn't visible.
6114
In either of these cases, since it's not possible to see out to an
6115
enclosing location, the current object has to provide its own interior
6116
description.
6117
6118
<p>This method is called from lookAroundPov(), which formerly
6119
performed the same test directly, so the default behavior hasn't
6120
changed.  This has been separated into a new method because the
6121
default condition isn't always ideal.  For example, if the player's
6122
inside a closed wooden booth with a small window that looks out to the
6123
enclosing location, and the player types LOOK AROUND, we'd want to
6124
describe the interior of the booth, not the outside location.  For
6125
this case, you could override isLookAroundCeiling() for the booth to
6126
return true even though the location is visible through the window.
6127
6128
</div>
6129
6130
<!------------------->
6131
<div class=firstentry>
6132
6133
The new TAction method getDobjInfo() returns the full ResolveInfo
6134
object associated with the current direct object.  Similarly, the
6135
new TIAction method getIobjInfo() returns the indirect object's
6136
ResolveInfo.
6137
6138
</div>
6139
6140
<!------------------->
6141
<div class=firstentry>
6142
6143
The parser now keeps track of the noun phrase that was parsed for
6144
each object involved in the command.  This information is kept in
6145
the ResolveInfo object, in the 'np_' property.  This information can
6146
be used, for example, to obtain the original text of the noun phrase
6147
that was resolved to a given object.  For example, to obtain the
6148
original text that resolved to the current direct object being
6149
processed in an action() method, you could write this:
6150
6151
<p><pre>
6152
   local txt = gAction.getDobjInfo().np_.getOrigText();
6153
</pre>
6154
6155
</div>
6156
6157
<!------------------->
6158
<div class=entry>
6159
6160
Due to a bug introduced in the previous release, the method
6161
PresentLater.makePresentByKeyIf() didn't work correctly if the
6162
condition argument was a function pointer.  In these cases, the
6163
routine called the function on the first object matching the key, and
6164
then used that same true/nil result for <i>every</i> matching object.
6165
(Thus, if the first matching object was to be revealed, every
6166
matching object was revealed; if the first was to be hidden, all were
6167
hidden.)  This has been corrected; the method once again calls the
6168
given function individually for each object matching the key.
6169
6170
</div>
6171
6172
<!------------------->
6173
<div class=entry>
6174
6175
Component objects are now hidden from EXAMINE ALL by default.  Since
6176
components are simply detail features of larger objects, it's usually
6177
enough to examine the larger objects; it usually doesn't make sense to
6178
also include the components separately in EXAMINE ALL responses.
6179
6180
</div>
6181
6182
<!------------------->
6183
<div class=entry>
6184
6185
By default, FOLLOW now reports a more helpful message when there's not
6186
enough information to carry out the command.  In the past, the default
6187
message was simply "You don't know where (the actor) went."  This was
6188
misleading when the real problem was that the actor's departure had
6189
been previously observed, but from some other location.  The new
6190
message is of this form: "The last place you saw (the actor) was (the
6191
room where we last saw him)."  Note that the library now keeps track
6192
of the last place we saw each actor, even when we didn't observe the
6193
actor leaving, to ensure that this new message is always accurate.
6194
6195
</div>
6196
6197
<!------------------->
6198
<div class=entry>
6199
6200
The "badness" levels of some of the grammar rules in the English
6201
parser have been re-ranked, to put the various error conditions in a
6202
different order.  In particular, the "miscellaneous noun phrase" rules
6203
now have a lower badness than any of the "missing noun phrase" rules.
6204
In the past, this relationship was reversed, which caused a subtle
6205
problem when a two-noun verb was used with a noun phrase containing a
6206
word not in the dictionary.
6207
6208
<p>Some background: In the English parser, certain grammar rules are
6209
defined specifically to match certain distinct patterns of erroneous
6210
user input.  The point of matching invalid input is to recognize it
6211
and respond intelligently to it, rather than issue a blanket error
6212
message.  Most of these invalid constructs are marked with "badness"
6213
levels, which tells the parser to match them only as a last resort, so
6214
that we match a valid grammar rule over one of these special error
6215
rules whenever possible.
6216
6217
</div>
6218
6219
<!------------------->
6220
<div class=entry>
6221
6222
In the English grammar, each of the verbs with two noun slots (PUT X
6223
ON Y, ASK X ABOUT Y, etc.) has a corresponding special grammar rule
6224
that includes only the first noun slot (PUT X, ASK X, etc.), for cases
6225
where the player inadvertantly or intentionally types the command with
6226
only one noun.  In the past, these rules weren't marked with "badness"
6227
levels.  Now they are: these are treated as having "badness"
6228
equivalent to that of an empty noun phrase.  This ensures that they'll
6229
be matched only as a last resort, when there isn't a more "correct"
6230
interpretation of the phrase.
6231
6232
</div>
6233
6234
<!------------------->
6235
<div class=entry>
6236
6237
CollectiveGroup objects are now explicitly marked as unlisted in room
6238
or object contents or in inventories (that is, a CollectiveGroup's
6239
isListed, isListedInContents, and isListedInInventory properties now
6240
return nil).  In the past, collective group objects incorrectly showed
6241
up in these listings as separate objects under certain circumstances,
6242
such as when their individuals were self-illuminating (brightness = 1)
6243
and the enclosing room was dark.
6244
6245
</div>
6246
6247
<!------------------->
6248
<div class=entry>
6249
6250
In the past, the description of a dark room listed every visible
6251
self-illuminating object, even including those being carried by the
6252
actor doing the looking.  Now, the description excludes objects in the
6253
actor's inventory, since these objects aren't part of the actor's
6254
surroundings.
6255
6256
</div>
6257
6258
<!------------------->
6259
<div class=entry>
6260
6261
In the past, the INVENTORY command included in its listing any items
6262
that were being directly held, even if they weren't visible, on the
6263
assumption that the actor could identify these items by touch alone.
6264
This has now been refined slightly: instead of unconditionally
6265
including directly-held items in the listing, the library now includes
6266
directly-held items that the actor already knows about, as indicated
6267
by the actor's knowsAbout() method.  The rationale is almost the same
6268
as before, but this change means that we no longer assume that the
6269
actor can identify an item by touch unless the actor already knows
6270
about the item.  Of course, this change doesn't affect the listing of
6271
visible items - visible items are listed whether previously known or
6272
not.
6273
6274
</div>
6275
6276
<!------------------->
6277
<div class=entry>
6278
6279
The "finish option" handler for RESTORE (finishOptionRestore) now
6280
terminates any remaining processing on the command line that triggered
6281
the finish options, when the RESTORE is successful.  This ensures that
6282
when the finish options are triggered from somewhere in the middle of
6283
a command (such as in a beforeAction method), there will be no strange
6284
side effects from carrying out the rest of the triggering command.
6285
6286
</div>
6287
6288
<!------------------->
6289
<div class=entry>
6290
6291
In the English grammar, LOOK OUT is now a synonym for LOOK THROUGH.
6292
This allows constructs like LOOK OUT WINDOW, which is more natural
6293
for some objects than LOOK THROUGH but has the same meaning in
6294
virtually all cases.
6295
6296
</div>
6297
6298
<!------------------->
6299
<div class=entry>
6300
6301
In the English grammar, the acceptable phrasing for the SitOn command
6302
no longer includes "sit <i>object</i>" or "sit down <i>object</i>."
6303
These phrasings aren't grammatical, but they were included to match
6304
intransitive inputs (SIT and SIT DOWN) and then ask for the missing
6305
direct object phrase.  Now, rather than matching the intransitive
6306
forms using the main SitOn rule, they're matched using the SitOnWhat
6307
rule.  The same change applies to the LieOn rules.
6308
6309
</div>
6310
6311
<!------------------->
6312
<div class=entry>
6313
6314
UnlistedProxyConnector.primaryConn is now initialized to TadsObject by
6315
default.  In rare cases, game code might invoke a property of an
6316
UnlistedProxyConnector before the object is constructed; this new
6317
default (rather than nil) provides reasonable behavior in these cases,
6318
without requiring an added run-time test for a nil primaryConn.
6319
6320
</div>
6321
6322
<!------------------->
6323
<div class=entry>
6324
6325
In the English messages, the AutoClosingDoor's announcement (of the
6326
door having automatically closed) now has a leading paragraph break,
6327
to set it off from the room description or other travel report that
6328
usually precedes the announcement.
6329
6330
</div>
6331
6332
<!------------------->
6333
<div class=entry>
6334
6335
The English library's rules have changed slightly for substituting
6336
reflexive pronouns in message strings.  In the past, the library
6337
always substituted a reflexive pronoun when an "objective-case"
6338
parameter matched the subject of the sentence; for example, in the
6339
message string "{You/he} can't eat {the dobj/him}," if the direct
6340
object was the same as the actor, the message would be "You can't eat
6341
yourself" (rather than simply "You can't eat you").  The new rule is
6342
<i>almost</i> the same, but has a new exception: if the <i>parameter
6343
name</i> of an objective-case parameter is the same as that of the
6344
subject of the sentence, the reflexive substitution is not used.
6345
6346
<p>For example, the library now displays "{You/he} close{s} the door
6347
behind {you/him}" as "You close the door behind you."  The old rule
6348
would have used "behind yourself" instead, but the new exception kicks
6349
in because both the subject ("{You/he}") and the objective-case item
6350
("{you/him}") refer to the 'actor' parameter object.
6351
6352
<p>The reason the automatic reflexive substitution exists in the first
6353
place is that it allows you to write a message string that refers to
6354
multiple parameters that <i>might</i> end up being the same object
6355
some of the time.  In the first example ("{You/he} can't eat {the
6356
dobj/him}"), the direct object and the actor might sometimes be the
6357
same, but usually aren't; since the library automatically provides the
6358
reflexive pronoun when the direct object happens to be the same as the
6359
actor, the same message string works for any combination of objects
6360
("You can't eat yourself" vs. "You can't eat the deck chair").
6361
However, this rule is too aggressive without the exception.  The point
6362
of the exception is to give authors exact control in cases where they
6363
know <i>in advance</i> that the subject and objective-case object will
6364
be the same, by virtue of the fact that the message is referring to
6365
the same parameter by name in both cases.  In these cases, there's no
6366
need for the library to provide reflexive pronouns conditionally,
6367
because the author knows in advance that the objects will always be
6368
the same - so the author will know whether or not the reflexive
6369
pronoun is desired, and will write it that way, or not, as desired.
6370
6371
</div>
6372
6373
<!------------------->
6374
<div class=entry>
6375
6376
If an exception occurs during an NPC's turn (in ActorState.takeTurn,
6377
for example), the scheduler will now count the NPC's turn as over, so
6378
that other NPC's get a chance to run before the same NPC takes another
6379
turn.  In the past, an uncaught exception during an NPC's turn
6380
bypassed the turn-counting for the NPC, so the same NPC got another
6381
turn immediately; in some cases, this caused the NPC to try the same
6382
erroneous operation again, which set up an infinite loop as the
6383
erroneous NPC code was invoked over and over without giving anyone
6384
else a chance to run.  The same change applies to fuses, daemons, and
6385
any other "schedulable" object.
6386
6387
</div>
6388
6389
<!------------------->
6390
<div class=entry>
6391
6392
In the English library, SCRIPT ON is now accepted as a synonym for
6393
SCRIPT (for consistency with SCRIPT OFF), and RECORD ON as a synonym
6394
for RECORD.  In addition, the RECORD ON/OFF messages have been changed
6395
to sound less geeky (they formerly referred to "RECORD mode," but now
6396
talk about "command recording" instead).
6397
6398
</div>
6399
6400
<!------------------->
6401
<div class=entry>
6402
6403
In the English library, "inside" and "inside of" are now accepted in
6404
locational qualifier phrases (as in "read the coin inside the box").
6405
6406
</div>
6407
6408
<!------------------->
6409
<div class=entry>
6410
6411
When the player looks behind or through a closed door, the library now
6412
assumes that the player's intention is to open the door to see what's
6413
on the other side.  So, the library now applies an objOpen
6414
precondition to these commands, which will implicitly open the door if
6415
it's closed.
6416
6417
<p>In addition, in the case of LOOK BEHIND, the library uses a special
6418
message if the implicit Open was applied: "Opening the door reveals
6419
nothing unusual."  This message emphasizes that we're looking through
6420
the passage, not at the space created between the door and the
6421
adjacent wall (if such a thing is applicable).
6422
6423
<p>When we look behind a door that was already open, the library
6424
assumes that the player's intention is simply to look at the back side
6425
of the door, or the space between the door and the adjacent wall.  In
6426
this case, the inherited Thing message ("you see nothing unusual
6427
behind the door") is used.
6428
6429
</div>
6430
6431
<!------------------->
6432
<div class=entry>
6433
6434
LOOK THROUGH PASSAGE now has a custom response when the passage is
6435
open: "You can't see much through (the passage) from here."  In the
6436
real world, we can typically look through a passage into the next
6437
room, but the library world model doesn't actually allow us to see
6438
anything in the next room; so we don't want to say that we can't see
6439
through the passage at all, but at the same time we can't actually say
6440
we see anything.  The new default suggests that we can in principle
6441
see some distance through the passage, but not far enough to see
6442
anything in the connected location.
6443
6444
<p>When a passage is closed, the inherited Thing message ("you can't
6445
see anything through (the passage)") is used instead, since a closed
6446
passage is assumed to be something opaque, such as a closed door.
6447
6448
</div>
6449
6450
<!------------------->
6451
<div class=entry>
6452
6453
Looking through, under, or behind a room part now yields a custom
6454
response that says that you simply can't do that, rather than using
6455
the inherited Thing defaults (which say that you can't see anything
6456
there).  For room parts, it doesn't generally make sense to perform
6457
any of these actions, which the new custom messages try to convey.
6458
6459
</div>
6460
6461
<!------------------->
6462
<div class=entry>
6463
6464
If a player types simply GO or WALK, the library now displays a more
6465
helpful message: "You'll have to say which way to go."  In the past,
6466
the parser didn't recognize that phrasing at all, so responded with
6467
the standard unknown-verb message.
6468
6469
</div>
6470
6471
<!------------------->
6472
<div class=entry>
6473
6474
PathPassage now uses a custom message for STAND ON: "If you want to
6475
follow the path, just say so."  The inherited default ("That isn't
6476
something you can stand on") doesn't make a lot of sense for paths,
6477
but at the same time, we don't want to treat every path passage as a
6478
separate nested room, so this message seeks to convey that the action
6479
might be logical in the real-world but isn't required in the game.
6480
6481
</div>
6482
6483
<!------------------->
6484
<div class=entry>
6485
6486
Actor now handles a command of the form PUT ME IN <i>container</i> by
6487
replacing it with ENTER <i>container</i>.  This is done any time the
6488
direct object is the target actor.
6489
6490
<p>In addition, the actor is now excluded in all cases from being the
6491
default direct object for PUT IN.  In the past, the actor was selected
6492
as the default if there was nothing better, which occasionally led to
6493
odd results.
6494
6495
</div>
6496
6497
<!------------------->
6498
<div class=entry>
6499
6500
Actor now treats the commands PUT ON and PUT UNDER as illogical when
6501
applied to oneself (as in PUT ME ON THE TABLE).
6502
6503
</div>
6504
6505
<!------------------->
6506
<div class=entry>
6507
6508
Thing now calls verifyMoveTo() to verify a DROP command <i>only</i>
6509
when the object is being held by the actor performing the command.
6510
When the object isn't being held, the DROP will be illogical on that
6511
basis alone - the object definitely won't be moved, so there's no
6512
reason to verify the move.  This is important because some subclasses
6513
use verifyMoveTo() to report other catch-all conditions ("that's too
6514
heavy to move," etc), which in the past sometimes were reported
6515
instead of the more basic problem ("you're not holding that").  By
6516
avoiding the call to verifyMoveTo() when the object isn't being held,
6517
we ensure that the more basic problem is always reported instead of
6518
any applicable catch-all condition.
6519
6520
</div>
6521
6522
<!------------------->
6523
<div class=entry>
6524
6525
The Immovable class incorrectly handled certain two-object actions
6526
(such as PUT IN, PUT ON, MOVE WITH) by failing in the action()
6527
routine.  This still allowed the <i>other</i> object involved in the
6528
command to handle the action successfully.  For these two-object
6529
actions, the class needs to block the action in the check() routine
6530
instead, which it now does.
6531
6532
</div>
6533
6534
<!------------------->
6535
<div class=entry>
6536
6537
When an AgendaItem throws an exception (including things like 'exit'
6538
signals) out of its invokeItem() method, the library now automatically
6539
marks the agenda item as finished (by setting its isDone property to
6540
true).  In most cases, if an agenda item throws an exception, it's
6541
because something went wrong; since the same thing would probably go
6542
wrong again if the item were tried again, allowing the agenda item to
6543
remain in its "ready" state typically resulted in an infinite loop as
6544
the actor kept trying the same item over and over.  This change avoids
6545
infinite loops in these cases by ensuring that an item that throws an
6546
error isn't retried automatically.
6547
6548
</div>
6549
6550
<!------------------->
6551
<div class=entry>
6552
6553
When an object provides its own custom definition for a library
6554
message (via one of the xxxMsg properties), it can now be defined as a
6555
simple single-quoted string, even if the library method for the
6556
message normally takes one or more arguments.  This makes it more
6557
convenient to define these custom messages.  Of course, you can still
6558
provide a full method definition that takes the same arguments as the
6559
corresponding library message method.
6560
6561
</div>
6562
6563
<!------------------->
6564
<div class=entry>
6565
6566
Settable now applies a touchObj precondition to the SetTo action.
6567
This ensures, for example, that a dial is reachable before it can be
6568
turned to a new setting.
6569
6570
</div>
6571
6572
<!------------------->
6573
<div class=entry>
6574
6575
The Floor class now includes a touchObj precondition for StandOn,
6576
SitOn, LieOn, and (as an indirect object for) PutOn.  This ensures
6577
that a floor in a connected but unreachable room (such as a room
6578
connected by distance) will be ruled out as a potential target object
6579
for these verbs, avoiding poor defaults and unnecessary disambiguation
6580
prompts.
6581
6582
</div>
6583
6584
<!------------------->
6585
<div class=entry>
6586
6587
The touchObj precondition now considers a distant object illogical
6588
during its 'verify' phase.
6589
6590
<p>In the past, this precondition treated an object that was visible
6591
but not reachable as still potentially logical, but at reduced
6592
likelihood.  The reasoning was that the obstruction might be easily
6593
removable via an implied action.  For example, an object inside an
6594
openable glass case could be made touchable by opening the glass
6595
case, which could be performed as an implied action.  However, in
6596
the case of distance, there's not usually any way to remove the
6597
obstruction automatically, so there's no point in considering the
6598
object to be logical, even at reduced likelihood.  The precondition
6599
still does exactly this for objects that aren't at a distance, but
6600
now assumes that distance can't be resolved automatically.
6601
6602
</div>
6603
6604
<!------------------->
6605
<div class=entry>
6606
6607
In the past, if the player used a SEARCH command on an Openable, and
6608
the object was closed, the implied OPEN action showed the
6609
newly-revealed contents of the object.  The main SEARCH command that
6610
triggered the OPEN also showed the Openable's contents, so the
6611
contents were listed twice.  Openable now omits the redundant contents
6612
listing for the implied OPEN when the main command is SEARCH, just as
6613
it's long done when the main command is LOOK IN.
6614
6615
</div>
6616
6617
<!------------------->
6618
<div class=entry>
6619
6620
A "conversational" command (HELLO, GOODBYE, YES, NO) now consistently
6621
counts as a turn for the issuing actor, even when a target actor is
6622
specified (as in "BOB, HELLO").  This corrects a subtle inconsistency
6623
that occurred when a conversational command was directed to an NPC
6624
that had a pending agenda item.  In the past, explicitly directing a
6625
conversational command to such an actor ("BOB, HELLO") prevented the
6626
agenda item from executing on the same turn, because specifying the
6627
target actor caused the turn to count against the NPC's turn counter
6628
rather than the PC's; but leaving out the target actor (as in saying
6629
simply "HELLO") counted the action as a PC turn, allowing the NPC to
6630
carry out its agenda item.  Now, both forms of the command ("HELLO"
6631
and "BOB, HELLO") have the same turn-counting treatment, so a pending
6632
agenda item will be allowed to proceed in either case.
6633
6634
</div>
6635
6636
<!------------------->
6637
<div class=entry>
6638
6639
The HELLO, GOODBYE, YES, and NO commands now find a suitable default
6640
actor to talk to if the target actor isn't specified (that is, if the
6641
command entered is simply something like "HELLO" rather than "BOB,
6642
HELLO").  If there's a current interlocutor, and it's still within
6643
earshot, then it's the default.  Otherwise, we look for a suitable
6644
default direct object for a TALK TO command.  This makes things more
6645
convenient for the player, since it allows the player to omit the
6646
target actor any time only one suitable actor is present.
6647
6648
</div>
6649
6650
<!------------------->
6651
<div class=entry>
6652
6653
In the past, saying BYE to an actor in a conversation-ready state
6654
(that is, an actor ready for a stateful conversation, but not
6655
currently in conversation) caused a run-time error.  This has been
6656
corrected.
6657
6658
</div>
6659
6660
<!------------------->
6661
<div class=entry>
6662
6663
Non-conversational topic entries (those with the isConversational
6664
property set to nil) now leave the actor's ConvNode unchanged.
6665
Conceptually, a response that doesn't involve any conversation
6666
shouldn't affect the thread of an ongoing conversation, so it
6667
makes more sense for such topics to leave the ConvNode unchanged.
6668
6669
</div>
6670
6671
<!------------------->
6672
<div class=entry>
6673
6674
In the past, Thing.lookAroundWithin() generated a slightly strange
6675
description when the point of view was a remote room, and the room
6676
containing the actor doing the looking was visible from the remote
6677
room.  In these cases, the actors were described as being "here" ( as
6678
in "Bob is standing here"), even though the "here" in this kind of
6679
description is more properly the remote point-of-view room.  The
6680
actors are now described as though they're in a remote room ("Bob is
6681
standing in the cave"), which is consistent with the perspective of
6682
the rest of the description.
6683
6684
</div>
6685
6686
<!------------------->
6687
<div class=entry>
6688
6689
In the past, no turn was counted for giving an actor an order (BOB, GO
6690
NORTH) that was refused in the actor's obeyCommand() method.  This
6691
didn't entirely make sense, since merely attempting to give an order
6692
to an actor is an in-game action, from the player's perspective.  This
6693
has been changed so that giving an order that's refused counts as one
6694
turn.
6695
6696
</div>
6697
6698
<!------------------->
6699
<div class=entry>
6700
6701
In the past, if an actor was in an accompanying-travel state, carrying
6702
the actor and then traveling to a new room caused a run-time error.
6703
The run-time error has been fixed.
6704
6705
<p>In addition, the accompanying-travel state is now ignored when the
6706
actor is being carried.  When an NPC is being carried, it will
6707
naturally move along with the actor it's accompanying, just as all of
6708
the actor's other inventory items do by virtue of being carried.  We
6709
therefore don't want the NPC to separately travel to the new location,
6710
because doing so makes the actor drop the NPC.
6711
6712
</div>
6713
6714
<!------------------->
6715
<div class=entry>
6716
6717
Thing now defines the methods canSee(obj), canHear(obj), and
6718
canSmell(obj).  In the past, these were defined only by Actor, not by
6719
Thing, since only actors have senses that allow perception of the
6720
physical surroundings.  In some cases, though, an actor uses an
6721
inanimate device as a point of view (a television monitor hooked up to
6722
a remote camera, for example), and in these cases it's necessary to
6723
check visibility (or other senses) from one inanimate object to
6724
another.  The new methods provide this capability.  They can be
6725
overridden as needed; for example, a camera that operates in the
6726
infrared might want to override canSee() to calculate visibility in a
6727
custom "infraredSight" sense rather than in the basic "sight" sense.
6728
6729
</div>
6730
6731
<!------------------->
6732
<div class=entry>
6733
6734
The NOTE command is now ignored for the purposes of the AGAIN command.
6735
For example, if you type INVENTORY, then type NOTE SOMETHING, then
6736
type AGAIN, the game will repeat the INVENTORY command.  There's no
6737
point in repeating a NOTE command, and NOTE is a sort of side
6738
conversation between player and author anyway, so it makes sense for
6739
AGAIN to act like the NOTE never happened.
6740
6741
</div>
6742
6743
<!------------------->
6744
<div class=entry>
6745
6746
The SAVE command is now ignored for the purposes of AGAIN.  There's no
6747
point in repeating a SAVE command immediately, as nothing will have
6748
changed in the game state between two consecutive SAVE commands, and
6749
hence no re-saving is warranted.
6750
6751
</div>
6752
6753
<!------------------->
6754
<div class=entry>
6755
6756
After a game is successfully restored, the memory of the previous
6757
command is forgotten, so the AGAIN command cannot be used.  This
6758
ensures that there's no confusion about whether AGAIN refers back to
6759
the RESTORE command (which would be pointless, as it would just
6760
re-restore the same state), the previous command in the same session,
6761
or the last command before SAVE from the restored game.
6762
6763
</div>
6764
6765
<!------------------->
6766
<div class=entry>
6767
6768
When a "finish options" menu is presented (with finishGame() or
6769
finishGameMsg()), and the player selects the UNDO option, the library
6770
now treats UNDO as the last command for the purposes of AGAIN.  That
6771
is, if the player answers a finish-options prompt with UNDO, and then
6772
types AGAIN, the library performs another UNDO.  (In the past, the
6773
game repeated the command that led to the finish-options prompt, since
6774
that was the last actual command.  However, most players wouldn't
6775
think to make this distinction, and wouldn't want to repeat whatever
6776
command led to the game-ending prompt anyway, so the most reasonable
6777
interpretation of an immediate AGAIN is to perform another UNDO.)
6778
6779
</div>
6780
6781
<!------------------->
6782
<div class=entry>
6783
6784
The RESTORE command is now ignored for the purposes of the UNDO
6785
command.  When a RESTORE succeeds, there's no way to undo anything:
6786
the restore itself can't be undone, and the incoming restored state
6787
initially doesn't have any undo history.  When the RESTORE fails, it
6788
won't make any changes to the game state, so there's nothing about the
6789
RESTORE itself to undo.  The main effect of this change is that typing
6790
UNDO after a failed RESTORE undoes the last undoable command
6791
immediately before the RESTORE.
6792
6793
</div>
6794
6795
<!------------------->
6796
<div class=entry>
6797
6798
In the past, if the player typed an OOPS command at the wrong time
6799
(when there wasn't any spelling error to correct), it was counted as a
6800
turn.  This was undesirable because OOPS is a meta command, not an
6801
in-game action.  The command no longer counts as a turn.
6802
6803
</div>
6804
6805
<!------------------->
6806
<div class=entry>
6807
6808
In the English library, a string pre-parser now wraps the comment text
6809
of a NOTE command in quotation marks, <i>if</i> the text contains any
6810
punctuation marks or the word THEN.  This allows players to enter
6811
arbitrary free-form text in NOTE remarks without any danger of
6812
confusing the parser.
6813
6814
</div>
6815
6816
<!------------------->
6817
<div class=entry>
6818
6819
The formatting in the English instructions has been tweaked slightly
6820
to make it more consistent.  In addition, the parsing of the responses
6821
to the INSTRUCTIONS prompt had a couple of small problems that have
6822
now been corrected.
6823
6824
</div>
6825
6826
<!------------------->
6827
<div class=entry>
6828
6829
A bug in the English library caused message substitution strings of
6830
form "{it's dobj/he's}" (that is, with an apostrophe-S on each example
6831
word, and the parameter name written in the middle of the two example
6832
words) to be expanded incorrectly.  This has been corrected.
6833
6834
</div>
6835
6836
<!------------------->
6837
<div class=entry>
6838
6839
In the English library, the methods (theNamePossNoun, theNamePossAdj)
6840
that build the default possessive name based on the base name of an
6841
object now add an apostrophe-S to a plural name that doesn't end in
6842
"s".  In the past, a bare apostrophe was always added to a plural
6843
name, which produced the wrong results for certain words (the men',
6844
the children', the fish').
6845
6846
</div>
6847
6848
<!------------------->
6849
<div class=entry>
6850
6851
The English library's method that builds the default plural name of
6852
an object (pluralNameFrom) now handles abbreviations more in keeping
6853
with conventional English usage:
6854
6855
<ul>
6856
6857
<li>For single letters, the method now adds an apostrophe-S to small
6858
letters (a's, b's, c's) and to the capital letters A, E, I, M, U, and
6859
V (A's, E's, etc).  For other capital letters, and for non-letters,
6860
the method simply adds an "s" (Bs, Cs, Ds).  (The apostrophe-S
6861
capitals are special because they could be confused with words or
6862
common abbreviations if we just added an "s".)
6863
6864
<li>For words that end in a capital letters or a digit, the method now
6865
just adds "s" (CPAs, PCs, MPs, 1970s, 20s).
6866
6867
<li>For words that end in a period, the method adds apostrophe-S
6868
(Ph.D.'s, M.A.'s).
6869
6870
</ul>
6871
6872
</div>
6873
6874
<!------------------->
6875
<div class=entry>
6876
6877
The new Thing property objInPrep can be used to specify the
6878
preposition to use when describing another object as being within a
6879
given object.  In the English library, the default for Thing is 'in'.
6880
Note that the existing property actorInPrep is now defined by default
6881
as returning the same value as the new objInPrep, since for most
6882
purposes they have the same meaning.
6883
6884
</div>
6885
6886
<!------------------->
6887
<div class=firstentry>
6888
6889
A new message is displayed when a Throw command fails because a
6890
DistanceConnector is in the way.  In the past, the library used the
6891
default Thing message, which describes the projectile as bouncing
6892
off the object that's in the way.  In the case of a distance connector,
6893
this doesn't make any sense.  The library now uses a custom message
6894
that describes the projectile as falling short of the target.
6895
6896
</div>
6897
6898
<!------------------->
6899
<div class=firstentry>
6900
6901
In the past, if an object was thrown through a MultiLoc connector to a
6902
separate top-level room, the object sometimes incorrectly landed on
6903
the originating side of the connector rather than on the target side.
6904
This only happened when the MultiLoc was a peer of the target.  The
6905
thrown object now correctly lands within the target's top-level
6906
location rather than within the origin's top-level room.
6907
6908
</div>
6909
6910
<!------------------->
6911
<div class=entry>
6912
6913
The ComplexContainer class now refers the methods isOpen, isLocked,
6914
makeOpen, and makeLocked to the subContainer, if it's non-nil.  A
6915
complex container appears in the game world as effectively enclosing
6916
the contents of its sub-container, because the sub-container doesn't
6917
usually appear as a distinct object in the game world, so the apparent
6918
open and locked status of the complex container are almost always the
6919
same as for its sub-container.  These new referrals make it a little
6920
easier to write code by removing the need to refer explicitly to the
6921
sub-container when checking or changing the open or locked status of a
6922
complex container.
6923
6924
</div>
6925
6926
<!------------------->
6927
<div class=entry>
6928
6929
An error in BasicOpenable.makeOpen() caused a run-time error ("wrong
6930
number of arguments") in certain cases when a BasicOpenable was used
6931
with multiple inheritance.  In particular, the error ocurred when an
6932
object derived from BasicOpenable also had at least one additional
6933
superclass which itself defined makeOpen(), and the additional
6934
superclass was placed after the BasicOpenable subclass in the object's
6935
superclass list.  This has been fixed.
6936
6937
</div>
6938
6939
<!------------------------------- 3.0.7 --------------------------------->
6940
<div class="sepbar"><a name='307'></a>3.0.7</div>
6941
<p><b><i>Released 6/12/2004</i></b>
6942
<p>
6943
6944
<div class=firstentry>
6945
6946
The default rules in Thing and NonPortable for contentsListed and
6947
contentsListedInExamine weren't quite right, so they've been changed
6948
slightly.  The new default rules are that an object's contents are
6949
<i>always</i> listed when the object is directly examined, and they're
6950
listed in "indirect" examinations if (1) the object is itself
6951
mentioned somehow in the indirect description, and (2) its contents
6952
would be listed in a direct examination.
6953
6954
<p>(A couple of definitions might help.  A "direct examination" is
6955
what happens when the player explicitly EXAMINEs the object; an
6956
"indirect examination" occurs when looking at the room, showing an
6957
inventory listing, or directly examining an enclosing object.  An
6958
object is "mentioned somehow" in an indirect description if either (1)
6959
it's included in the basic generated list of portable items within the
6960
enclosing object that's being examined, as determined by the isListed
6961
property, or (2) it shows as special description, as determined by the
6962
useSpecialDesc method.)
6963
6964
<p>The reasoning behind the new rules is as follows.  First, on
6965
directly examining an object, its contents should almost always be
6966
mentioned; we'd want to conceal the contents only in unusual cases, so
6967
the default for contentsListedInExamine is simply 'true'.  Second,
6968
when indirectly examining an object, we'd normally want its contents
6969
to be included in the description, since they're also, indirectly, the
6970
contents of the enclosing object being examined; however, when the
6971
object itself isn't mentioned in the indirect examination, then we
6972
probably don't want to mention its contents, either.  Furthermore,
6973
if for some reason we've chosen to conceal the contents even when
6974
the object is directly examined, then we almost certainly want to
6975
conceal the contents in indirect examinations as well.
6976
6977
<p>The rule is slightly different, and simpler, in NonPortable:
6978
contentsListed simply returns the value of contentsListedInExamine.
6979
The reason for this different default is that a NonPortable is almost
6980
always a fixed feature of its enclosing objects, and as such is
6981
almost always mentioned, to the extent it merits mentioning, as part
6982
of the custom description of the room or containing object.  This is
6983
sometimes accomplished with a specialDesc, but not always, so the
6984
absence of a specialDesc isn't sufficient reason to think that the
6985
object isn't mentioned.  Since a NonPortable almost always gets some
6986
kind of mention in indirect examinations, then, the default is that
6987
its contents are listed in these cases, too, as long as they'd be
6988
listed in a direct examination.
6989
6990
</div>
6991
6992
<!------------------->
6993
<div class=entry>
6994
6995
The Consultable class now requires that the object be both touchable
6996
and visible for the Consult action (in the past, it only had to be
6997
touchable).  Consultables are typically things like books or maps
6998
whose contents are read visually, so in most cases it only makes sense
6999
to consult a consultable when it's visible.  This change prevents
7000
lookup up information in a consultable while in the dark, for example.
7001
7002
</div>
7003
7004
<!------------------->
7005
<div class=entry>
7006
7007
The new property disambigPromptOrder can be given to any VocabObject
7008
(any simulation object with vocabulary words) to control its ordering
7009
in an interactive disambiguation prompt ("Which book do you mean, the
7010
red book, or the blue book?").  When a disambiguation prompt is shown,
7011
the objects in the prompt are listed in ascending order of this
7012
property value.  By default, disambigPromptOrder is 100; since all
7013
objects have this same default, if you don't override it for any
7014
objects, the ordering of disambiguation lists will be arbitrary.
7015
7016
<p>Arbitrary ordering is usually fine.  However, it's nice to be able
7017
to control the order when objects have ordinals in their names ("first
7018
book," "third button," etc), to make the list order match the nominal
7019
order.  For example, if you have a group of books named "first book,"
7020
"second book," and "third book," you could give these objects
7021
disambigPromptOrder values of 101, 102, and 103, respectively.
7022
7023
</div>
7024
7025
<!------------------->
7026
<div class=entry>
7027
7028
When the parser processes a response to an interactive disambiguation
7029
question ("Which book do you mean..."), it now takes a vocabulary
7030
match to an ordinal name as superseding the alternative interpretation
7031
as a list position.  For example:
7032
7033
<p><pre>
7034
   Which book do you mean, the red book, the first black book, or the
7035
   second black book?
7036
<br>
7037
<br>   &gt;second
7038
</pre>
7039
7040
<p>The parser will now interpret "second" as referring to "second black
7041
book."  In the past, it took this to mean the second item in the list,
7042
which in this case is "first black book"; this is hardly ever what
7043
the player means in these cases, though.
7044
7045
<p>(This change is actually a bug fix.  The parser already had logic
7046
to apply this precedence order, but it didn't work properly.  In
7047
particular, the "adjective ending" preference - the preference for
7048
avoiding a phrase that ends in an adjective - superseded the ordinal
7049
preference.  Adjective endings are obviously not a problem for
7050
disambiguation responses, though, so this has been changed.)
7051
7052
</div>
7053
7054
<!------------------->
7055
<div class=entry>
7056
7057
When the parser asks the player for disambiguation help to choose
7058
among several items that can be distinguished only by their location,
7059
and some of the items are in different top-level locations from the
7060
player character, the parser now describes the remote locations using
7061
the remote room names (rather than with the default "floor" or
7062
"ground" container, as was formerly the case).  This helps ensure
7063
that objects are distinguished properly when several top-level
7064
rooms are connected by sense connectors.
7065
7066
<p><pre>
7067
   Which coin do you mean, the one on the floor, or the one on the
7068
   balcony?
7069
</pre>
7070
7071
<p>In a related change, the parser now chooses a "local"
7072
interpretation of a locational qualifier in cases of ambiguity.  For
7073
example, if the player were to answer the question above with "the one
7074
on the floor," the parser would now assume that the player is talking
7075
about the coin in the local location (i.e., within the player
7076
character's top-level enclosing room).  In the past, if the balcony
7077
also had a floor, the locational qualifier would have been ambiguous.
7078
7079
</div>
7080
7081
<!------------------->
7082
<div class=entry>
7083
7084
The new function dataTypeXlat(val), defined in the system library file
7085
_main.t, returns the "translated" datatype for the given value.  This
7086
is almost identical to dataType(val), except that when 'val' is an
7087
anonymous function, the new dataTypeXlat() returns TypeFuncPtr rather
7088
than TypeObject.  In most cases, it's convenient to treat an anonymous
7089
function pointer value as though it were an ordinary static function
7090
pointer, because the two types are almost interchangeable in their
7091
usage; this function makes it easier to code such cases, because you
7092
don't have to worry about these two different ways that a
7093
function-pointer-like value might appear.
7094
7095
</div>
7096
7097
<!------------------->
7098
<div class=entry>
7099
7100
The new class AskTellShowTopic lets you combine responses for an
7101
object for ASK ABOUT, TELL ABOUT, and SHOW TO in a single topic
7102
response object.  Players sometimes find SHOW TO to be more natural
7103
than ASK ABOUT when an object is present and visible; this new class
7104
makes it convenient when you want to handle either command the same
7105
way.
7106
7107
</div>
7108
7109
<!------------------->
7110
<div class=entry>
7111
7112
A bug in Thing.lookAroundWithinContents caused an infinite loop when
7113
attempting to describe a location in which three or more top-level
7114
rooms were linked by sense connectors.  This is now fixed.
7115
7116
</div>
7117
7118
<!------------------->
7119
<div class=entry>
7120
7121
In 3.0.6q, BulkLimiter defined lookInDesc as doing nothing.  This was
7122
problematic because BulkLimiter is inherited by some special types of
7123
containers, such as Underside and RearSurface, that don't have
7124
interiors for the purposes of LOOK IN.  The problem showed up in
7125
Underside and RearSurface objects: attempting to LOOK IN these
7126
objects showed no reply at all, hence yielded the library's default
7127
"Nothing obvious happens" message.
7128
7129
<p>BulkLimiter no longer defines this property at all.  Instead, this
7130
functionality has been moved to Container and Surface.  Furthermore,
7131
BulkLimiter.examineInterior no longer shows the lookInDesc; instead
7132
Container and Surface now show the lookInDesc as part of their
7133
action() handler for the LOOK IN command.
7134
7135
</div>
7136
7137
<!------------------->
7138
<div class=entry>
7139
7140
The new Thing method hideFromDefault() is similar to hideFromAll(),
7141
but indicates that the object should be hidden from being used as a
7142
default for the given action (that is, it won't be considered as a
7143
possible default when the player types a command that omits one or
7144
more required noun phrases).  By default, this simply returns what
7145
hideFromAll() returns for the same action, since in general an object
7146
that's hidden from ALL should also be ignored for defaulting.
7147
7148
<p>This is a coarser-grained mechanism than using verify() routines
7149
for individual actions, but it's more convenient when you want to
7150
exclude an object from being used as a default for a large number of
7151
actions.
7152
7153
</div>
7154
7155
<!------------------->
7156
<div class=entry>
7157
7158
gActionIs(a) now returns true if 'a' is one of the specific-direction
7159
travel subclasses (NorthAction, SouthAction, etc), and the current
7160
action is a base Travel action that's going the same direction.  This
7161
makes it possible to test for a NORTH command simply by testing
7162
gActionIs(North), which is what you would have expected even in past
7163
versions if you hadn't known better.
7164
7165
<p>(In the past, it was necessary to write a test like this instead:
7166
(gActionIs(Travel) &amp;&amp; gAction.getDirection ==
7167
northDirection).  This two-part test was required because the grammar
7168
rules for NORTH, SOUTH, etc. generate the base Travel action instead
7169
of the specific-direction subclasses.  The grammar rules still do
7170
this, but gActionIs() now calls a new Action method, actionOfKind(),
7171
which TravelAction overrides to encapsulate the two-part test; since
7172
TravelAction does the test for you, there's no longer any need to
7173
write it out by hand.  You can still write the two-part test if you
7174
prefer, and it still works the same as it did before, but it's easier
7175
and clearer to just write gActionIs(North) and the like.)
7176
7177
</div>
7178
7179
<!------------------->
7180
<div class=entry>
7181
7182
The algorithm in Actor.tryMakingRoomToHold has been improved slightly.
7183
(This is the routine that automatically frees up space in an actor's
7184
hands, when the space is needed for the current explicit action, by
7185
moving things being held into "bags of holding.")  The change is a bit
7186
heuristic, but it should work well in most cases.  The new rule: when
7187
there are at least four items that can be moved into bags of holding,
7188
the routine will now find the two that were picked up most recently
7189
and move them to the end of the list of possible items.  In practice,
7190
it's rare to have to put away more than one or two items for a single
7191
action, so this change effectively ensures that the items picked up
7192
most recently won't be put away automatically.
7193
7194
<p>The point of this change is to avoid annoying situations where the
7195
game automatically puts away an object that you just picked up in
7196
order to do something with it.  These situations were especially
7197
annoying when they were entirely automatic (for example, the game
7198
picked up an object automatically, then put it away automatically in
7199
order to make room to pick up another object automatically, then had
7200
to go get the first object out again in order to use it).  It was
7201
rare for this to happen, but it looked pretty silly when it did.
7202
7203
<p>In a related change, the library now arranges the order of putting
7204
things away to ensure that if object A goes inside bag of holding B,
7205
and B goes inside another bag of holding C, then A will be put in B
7206
before B is put in C.  This was almost always the result anyway due
7207
to affinity ordering, but proper nesting order is now explicitly
7208
assured.
7209
7210
</div>
7211
7212
<!------------------->
7213
<div class=entry>
7214
7215
There are two new "illogical" status types that "verify" routines can
7216
use to indicate the logicalness of an action with greater precision.
7217
The library uses these new types when appropriate in its action handlers.
7218
The new types are:
7219
7220
<ul>
7221
7222
<li>illogicalAlready() - this indicates that the action is illogical
7223
because the condition the command seeks to create is already in
7224
effect.  For example, we're trying to TAKE an object that the actor is
7225
already holding, or we're trying to OPEN an object that's already
7226
open.  This new type is almost the same as illogicalNow(), but
7227
provides more detail about the condition.
7228
7229
<li>illogicalSelf() - this indicates that the action is illogical
7230
because it's attempting to use an object on itself in some invalid
7231
way.  For example, we're trying to PUT something inside itself.  This
7232
type is almost the same as illogical(), with the added detail that
7233
it's the self-application that makes the command impossible to carry
7234
out.
7235
7236
</ul>
7237
7238
</div>
7239
7240
<!------------------->
7241
<div class=entry>
7242
7243
The Passage class now considers a closed passage to be invisible in a
7244
dark room.  The reasoning is that, when a passage is open, enough
7245
light from the adjoining room (if the adjoining room is lit) comes
7246
through the passage to make the passage itself visible, although not
7247
enough comes through to light the current room; but when a passage is
7248
closed, not even this small amount of light comes through the passage.
7249
7250
</div>
7251
7252
<!------------------->
7253
<div class=entry>
7254
7255
In the past, the parser matched a plural phrase (such as EXAMINE
7256
BOXES) to the most likely subset of the matching in-scope objects, as
7257
determined by the "verify" logicalness ranking.  This was too
7258
restrictive; it wasn't at all the common-sense interpretation that
7259
most users would expect from a plural usage, which is simply to match
7260
everything that matches the vocabulary.
7261
7262
<p>This has been changed.  There are two possible behaviors, which you
7263
can control via a global configuration property,
7264
gameMain.filterPluralMatches:
7265
7266
<ul>
7267
7268
<li>If gameMain.filterPluralMatches is true, the parser excludes
7269
objects from matching the plural phrase if their "verify" routines
7270
include an "illogical-already" or an "illogical-self" result.  This
7271
means, for example, that TAKE BOOKS will exclude any books that are
7272
already being held, DROP BOOKS will exclude any books that aren't in
7273
the player's inventory.  This is the default.
7274
7275
<li>If gameMain.filterPluralMatches is nil, the parser simply uses
7276
<b>all</b> vocabulary matches for a plural.
7277
7278
</ul>
7279
7280
</div>
7281
7282
<!------------------->
7283
<div class=entry>
7284
7285
The English parser now handles pronouns better in the recently-added
7286
command phrasing TELL <i>actor</i> TO <i>do something</i>.  In
7287
particular:
7288
7289
<ul>
7290
7291
<li>A reflexive pronoun that agrees in number and gender with the
7292
actor will be treated as referring to the actor, as long as there's
7293
not a valid interpretation internal to the predicate.  For example,
7294
TELL BOB TO HIT HIMSELF will treat HIMSELF as referring to Bob.
7295
However, TELL BOB TO ASK BILL ABOUT HIMSELF will treat HIMSELF as
7296
referring to Bill, since that interpretation is entirely
7297
self-contained within the predicate.
7298
7299
<li>A regular pronoun that agrees in number and gender with the
7300
actor will be treated as referring to the actor.  This is especially
7301
important with possessives: TELL BOB TO DROP HIS BOOK will treat
7302
HIS as referring to Bob.
7303
7304
<li>A second-person pronoun is now considered to refer to the
7305
player character, rather than to the target actor.  For example,
7306
TELL BOB TO HIT YOU is taken to mean that Bob should hit the player
7307
character.
7308
7309
<li>The target actor is set as a pronoun antecedent for subsequent
7310
commands from the issuing actor.  For example, after TELL BOB TO GO
7311
NORTH, the command FOLLOW HIM will mean to follow Bob.
7312
7313
</ul>
7314
7315
</div>
7316
7317
<!------------------->
7318
<div class=entry>
7319
7320
The English parser now rejects the phrasing TELL <i>first actor</i> TO
7321
TELL <i>second actor</i> TO <i>do something</i>.  (It formerly
7322
accepted this, but it didn't handle it as stated: in effect, the first
7323
TELL TO was ignored, so the command was treated as simply TELL
7324
<i>second actor</i> TO <i>do something</i>.)
7325
7326
</div>
7327
7328
<!------------------->
7329
<div class=entry>
7330
7331
The English parser now accepts the commands SIT DOWN and LIE DOWN.
7332
The parser accepts these stated intransitively (i.e., without a
7333
direct object), but treats them as synonyms for SIT ON (something
7334
unspecified) and LIE ON (something unspecified), respectively.  That
7335
is, the parser tries to find a suitable default object to sit on, and
7336
prompts the player for the missing object it no default can be
7337
assumed.
7338
7339
</div>
7340
7341
<!------------------->
7342
<div class=entry>
7343
7344
In the English parser, when the command phrasing involves what looks
7345
like an indirect object phrase that doesn't match anything in the
7346
grammar, a "miscellaneous preposition phrase" production is matched.
7347
This type of production is now more consistent about reporting that
7348
"the story doesn't understand that command," to indicate that the
7349
structure of the verb phrase was unrecognized.  In the past, if the
7350
the direct or indirect object phrases were themselves unresolvable,
7351
the parser showed that error instead; this was often less useful,
7352
because the root problem in these cases is really that the overall
7353
verb phrasing can't be parsed.
7354
7355
</div>
7356
7357
<!------------------->
7358
<div class=entry>
7359
7360
The NOTE command now shows a warning if the transcript isn't
7361
currently being saved (with the SCRIPT command).  This command's main
7362
purpose is to let the player embed a comment in the session
7363
transcript, as a means of sending feedback to the author.  There's
7364
not a lot of point in using the command when the transcript isn't
7365
being saved, so there's a good chance that a player using the command
7366
thinks that a SCRIPT command is already in effect.  The warning calls
7367
the player's attention to this.  The warning is only issued the first
7368
time that NOTE is used without logging in effect, but this is reset
7369
each time logging is started and then stopped.
7370
7371
</div>
7372
7373
<!------------------->
7374
<div class=entry>
7375
7376
In the past, real-time events created during pre-initialization
7377
weren't set up properly, because the real-time manager's internal
7378
clock wasn't initialized until run-time start-up.  The clock now
7379
has a static initializer, ensuring that events created during preinit
7380
will have a valid time base.
7381
7382
</div>
7383
7384
<!------------------------------- 3.0.6q --------------------------------->
7385
<div class="sepbar"><a name='306q'></a>3.0.6q</div>
7386
<p><b><i>Released 5/9/2004</i></b>
7387
<p>
7388
7389
<div class=firstentry>
7390
7391
<p><b>Possible compatibility-breaking change:</b> The standard parser
7392
dictionary has been renamed from G_dict to cmdDict (for "command
7393
dictionary").  The dictionary is simply an object, and the new name is
7394
more consistent with other parser object names (in particular,
7395
cmdTokenizer, the standard parser tokenizer).
7396
7397
<p>It's relatively uncommon for game code to refer to the main
7398
dictionary directly, but you should search your code for references
7399
to G_dict and change the name to cmdDict.
7400
7401
7402
</div>
7403
7404
<!------------------->
7405
<div class=entry>
7406
7407
<p><b>Possible compatibility-breaking change:</b> The methods that
7408
describe an actor's location have been changed, in order to improve
7409
consistency and to simplify the code structure.  These changes are
7410
mostly internal to the library, so they're unlikely to affect
7411
existing code unless you've made some rather low-level customizations.
7412
7413
<p>The changes involve a lot of renaming and rerouting of internal
7414
method calls.  The list of changes below is divided into groups of
7415
related changes.
7416
7417
<p><b>Group 1:</b> The "nominal actor container" methods have been
7418
consolidated into a single method.
7419
7420
<ul>
7421
7422
<li>The methods getNominalStandingContainer,
7423
getNominalSittingContainer, and getNominalLyingContainer have been
7424
deleted.  In their place is a single new method,
7425
getNominalActorContainer, which takes the posture as a parameter.
7426
Since it's almost never necessary to differentiate the nominal actor
7427
container by posture, the single method approach is more convenient,
7428
and it's also more readily extensible to new postures.
7429
7430
</ul>
7431
7432
<p><b>Group 2:</b> The Posture object has been taken out of the loop,
7433
as it were, for the methods that describe actors.  The Posture
7434
object's role in the past was to break out these various methods into
7435
a separate version for each posture, and then further dispatch to the
7436
actor's nominal location: for example, the okayPostureChange method
7437
was split up into okayStand, okaySit, and okayLie.
7438
7439
<p>The original idea was that locations might want to customize
7440
extensively by posture, but in practice the multiplicity of methods
7441
turned out to be more trouble than it was worth.  With the present
7442
change, each set of Stand/Sit/Lie variations is now consolidated back
7443
into a single method, which makes the Posture object's role
7444
unnecessary, allowing it to be removed from the dispatch chain.
7445
It's still used in generating the final message, but in most cases
7446
this is now a simple matter of getting the posture's participle
7447
("sitting", etc) from the Posture object and using it to build the
7448
message string.
7449
7450
<p>The following list of changes will look daunting, but it's
7451
unlikely that existing game code will be much affected, as these
7452
methods were always meant mostly for internal use in the library.
7453
7454
<ul>
7455
7456
<li>Actor.actorHereDesc changes:
7457
7458
<ul>
7459
7460
  <li>Posture.actorHereDesc and libMessages.actorHereDesc have been
7461
  deleted.  Instead, the actor calls directly to roomActorHereDesc on
7462
  the nominal actor container.
7463
7464
  <li>The BasicLocation, Floor, and libMessages methods
7465
  actorStandingHere, actorSittingHere, and actorLyingHere have been
7466
  deleted, and replaced by the new method roomActorHereDesc.
7467
7468
  <li>The libMessages methods actorHereStandingOn, actorHereSittingOn,
7469
  and actorHereLyingOn have been deleted, and replaced by the new method
7470
  actorInRoom.
7471
7472
</ul>
7473
7474
<li>Actor.actorThereDesc changes:
7475
7476
<ul>
7477
7478
  <li>BasicLocation, Floor, and libMessages provide definitions of the
7479
  new method roomActorThereDesc.
7480
7481
  <li>NestedRoom.roomRemoteActorDesc has been renamed to
7482
  roomActorThereDesc, and the implementation has been moved from
7483
  NestedRoom to BasicLocation.
7484
7485
  <li>libMessages.nestedRoomRemoteActorDesc has been renamed to
7486
  actorInRemoteNestedRoom, and libMessages.roomRemoteActorDesc has
7487
  been renamed to actorInRemoteRoom.
7488
7489
</ul>
7490
7491
<li>Room status name changes - these affect the mechanism that
7492
generates room title addenda such as "(sitting in the chair)":
7493
7494
<ul>
7495
7496
  <li>Posture.statusPosture has been deleted.  Instead, the (newly
7497
  renamed) Actor.actorRoomNameStatus now handles this directly.
7498
7499
  <li>Actor.statusPosture has been renamed to actorRoomNameStatus, to
7500
  clarify and reflect the broader potential of its purpose.
7501
7502
  <li>The BasicLocation, Floor, and libMessages methods
7503
  statusStanding, statusSitting, and statusLying have been deleted, 
7504
  and replaced by the new method roomActorStatus.
7505
7506
  <li>The libMessages methods statusStandingOn, statusSittingOn,
7507
  and statusLyingOn have been deleted, and replaced by the new
7508
  method actorInRoomStatus.
7509
7510
</ul>
7511
7512
<li>Actor posture description changes:
7513
7514
<ul>
7515
7516
  <li>Posture.actorPostureDesc has been deleted.  Actor now handles
7517
  this directly.
7518
7519
  <li>The BasicLocation, Floor, and libMessages methods actorStandingDesc,
7520
  actorSittingDesc, and actorLyingDesc have been deleted, and replaced
7521
  with the new method roomActorPostureDesc.
7522
7523
  <li>The libMessages methods actorStandingOnDesc, actorSittingOnDesc,
7524
  and actorLyingOnDesc have been deleted, and replaced by the new
7525
  method roomActorPostureDesc.
7526
7527
</ul>
7528
7529
<li>Posture change acknowledgment changes - these affect the mechanism
7530
that generates the default responses to commands like SIT and STAND:
7531
7532
<ul>
7533
7534
  <li>Posture.okayPostureChange has been deleted.  Actor now handles
7535
  this directly.
7536
7537
  <li>The BasicLocation and Floor methods okayStand,
7538
  okaySit, and okayLie have been deleted, and replaced by the new
7539
  method roomOkayPostureChange.
7540
7541
  <li>The libMessages methods okayStandMsg, okaySitMsg, and okayLieMsg 
7542
  have been replaced by the new method okayPostureChangeMsg.
7543
7544
  <li>The playerActionMessages and npcActionMessages methods
7545
  okayStandOnObjMsg, okaySitOnObjMsg, and okayLieOnObjMsg have
7546
  been deleted, and replaced by the new method roomOkayPostureChange.
7547
7548
</ul>
7549
7550
<li>Changes to the mechanism that mentions that an actor is
7551
sitting/lying/standing in a nested room, as part of the EXAMINE
7552
description of the nested room:
7553
7554
<ul>
7555
7556
  <li>Posture.listActorPosture has been deleted.  Actor.listActorPosture
7557
  now calls the nominal actor container directly instead.
7558
7559
  <li>The BasicLocation and Floor methods listActorStanding, 
7560
  listActorSitting, and listActorLying have been deleted, and replaced
7561
  by the new method roomListActorPosture.
7562
7563
  <li>The libMessages methods listActorStandingOn, listActorSittingOn,
7564
  and listActorLyingOn have been deleted.  Their role has been subsumed
7565
  by actorInRoom.
7566
7567
</ul>
7568
7569
</ul>
7570
7571
<p><b>Group 3:</b> Actor "grouping" is now handled in BasicLocation,
7572
rather than only in NestedRoom.
7573
7574
<ul>
7575
7576
<li>The implementation of listWithActorIn() that was formerly in
7577
BasicChair has been moved to NestedRoom.  This means that actors
7578
without special descriptions are now grouped by default with other
7579
actors without special descriptions who are present in the same
7580
location and posture.
7581
7582
<li>NestedActorGrouper has been renamed to RoomActorGrouper, since
7583
it's now used for any room with actors to be grouped, not just nested
7584
rooms.
7585
7586
<li>In order to accommodate the wider range of cases where actor
7587
group lists are now generated by default, RoomActorGrouper now
7588
determines two additional bits of information: it gets the nominal
7589
actor container for the location containing the actors being listed,
7590
and it checks to see if the point-of-view actor is viewing the 
7591
listing from a "remote" location (a separate top-level room
7592
connected by a sense connector).  It uses this information to generate
7593
the group prefix and suffix messages differently than before:
7594
7595
<ul>
7596
7597
<li>If the nominal actor container is visible, the grouper calls the
7598
new methods actorInGroupPrefix() and actorInGroupSuffix() on the
7599
nominal actor container to generate the prefix and suffix messages.
7600
BasicLocation and Floor provide suitable default definitions of these
7601
new methods.
7602
7603
<li>If the nominal actor container isn't visible, but the actors are
7604
in a remote location, the new libMessages methods
7605
actorThereGroupPrefix() and actorThereGroupSuffix() are used.
7606
7607
<li>Otherwise, the new libMessages methods actorHereGroupPrefix()
7608
and actorHereGroupSuffix() are used.
7609
7610
</ul>
7611
7612
<li>Actor.actorListWith now returns an empty list if 'self' overrides
7613
specialDesc.  This ensures that a specialDesc defined on the actor
7614
will take precedence over any list group applied by the location.
7615
(This is more important now that BasicLocation applies actor grouping
7616
by default.)
7617
7618
<li>Actor.actorHereListWith has been renamed to actorListWith.  This
7619
method is used whether the actor is local, distant, or remote, but
7620
the old name incorrectly suggested the existence of a separate
7621
actorThereListWith in parallel with the actorHereDesc/actorThereDesc
7622
pair.
7623
7624
</ul>
7625
7626
<p><b>Group 4:</b> Miscellaneous minor changes to the generation
7627
of remote room actor descriptions.
7628
7629
<ul>
7630
7631
<li>NestedRoom.roomRemoteActorDesc now generates a more elaborate
7632
message by default, describing not only the actor's immediate
7633
location, but its outermost visible location as well.  If the actor's
7634
outermost visible location isn't the same as 'self', the method now
7635
invokes libMessages.nestedRoomRemoteActorDesc, which generates a
7636
message of this form: "Bob is in the dining room, sitting in the
7637
chair."
7638
7639
<li>The method inRoomName that was formerly defined in Room is now
7640
defined in Thing instead.  This ensures that a suitable default
7641
remote room name will be generated for nested rooms as well as
7642
top-level rooms.  In addition, the method now simply returns
7643
actorInName by default, which ensures that the preposition used in
7644
the default remote room name will match the one customized via
7645
actorInPrep, if necessary.
7646
7647
</ul>
7648
7649
</div>
7650
7651
<!------------------->
7652
<div class=entry>
7653
7654
The new TravelConnector method connectorGetConnectorTo() gives a
7655
travel connector a chance to scan any "secondary" connectors it knows
7656
about for a connection to a given destination.  In some cases, a
7657
travel connector encapsulates other travel connectors; these are
7658
secondary connectors in the sense that they're linked to the room only
7659
from the first connector, and thus the room can't find them on its
7660
own.  This new method provides a way for a room to query a connector
7661
for any secondary connectors it knows about, in order to find a
7662
connector to a given destination.  The base TravelConnector class
7663
provides a default implementation suitable for most subclasses,
7664
and AskConnector overrides the method to search its list of
7665
secondary connectors.  Thing.getConnectorTo calls the new method
7666
when searching for a connector to a given destination.
7667
7668
<p>The immediate practical benefit of the new method is that it makes
7669
it possible for scripted NPC travel to traverse AskConnectors.  In the
7670
past, an NPC encountering an AskConnector was typically unable to
7671
proceed, since the AskConnector didn't directly link to the
7672
destinations of its underlying connectors, and the underlying
7673
connectors typically weren't linked directly as directions to the
7674
enclosing room.  This made it impossible for the scripted NPC to find
7675
a suitable connector, and thus blocked the scripted travel.
7676
7677
</div>
7678
7679
<!------------------->
7680
<div class=entry>
7681
7682
The properties for choosing whether or not to list the contents of an
7683
object to list in EXAMINE and LOOK AROUND descriptions have been
7684
expanded slightly to provide more control and better consistency.
7685
These changes are all in the Thing class.
7686
7687
<p>The isListed property now returns, by default, the value of
7688
isListedInContents.  The meanings of these properties haven't
7689
changed: isListedInContents controls whether or not the object is
7690
listed when examining the object's <i>direct</i> container, whereas
7691
isListedInContents controls listability for examining <i>indirect</i>
7692
containers, including the enclosing room.  The reason for this change
7693
is that it's rare that we'd want an object to be unlisted when its
7694
direct container is examined, but still want it to be listed when
7695
enclosing containers are examined (whereas the reverse isn't entirely
7696
uncommon, since we sometimes want to mention an object only as a
7697
detail of its direct parent, but not of the broader room context).
7698
7699
<p>The new property contentsListedInExamine lets you control whether
7700
or not an object's direct contents are listed when the object is
7701
examined directly.  In the past, you could do this only by overriding
7702
examineListContents, but the new property makes it easier to control
7703
this behavior.  The new property returns the same thing that
7704
contentsListed used to return.
7705
7706
<p>The contentsListed property now returns the value of
7707
contentsListedInExamine by default.  This is parallel to the change
7708
to isListed.
7709
7710
<p>The new method getListedContentsInExamine() returns the list of
7711
direct contents that should be listed when the object is examined.
7712
This new method is the direct-examination equivalent of the existing
7713
getListedContents() method, and returns the same value that
7714
getListedContents() formerly returned: the subset of direct contents
7715
that appear in the sense info table passed to the method.
7716
7717
<p>The getListedContents() method now simply returns the result
7718
of calling getListedContentsInExamine().
7719
7720
<p>The method examineListContentsWith() now calls
7721
getListedContentsInExamine() to obtain the list of direct contents to
7722
list when examining an object.  In the past, this used the 'contents'
7723
property.  The method also checks the value of
7724
contentsListedInExamine, and skips the entire listing if this
7725
property is nil.
7726
7727
<p>These changes are all designed to be compatible with existing
7728
code.  They should simply add more flexibility and make certain
7729
behaviors easier to customize, but existing code shouldn't be
7730
affected.
7731
7732
</div>
7733
7734
<!------------------->
7735
<div class=entry>
7736
7737
In 3.0.6p, the library started listing the visible, portable contents
7738
of "remote" rooms as part of each room description.  The
7739
implementation had a problem when MultiLoc objects were involved,
7740
though: if a MultiLoc object appeared in more than one of the
7741
connected top-level rooms <i>and</i> had portable contents, those
7742
contents were listed several times - once for each connected
7743
top-level room in which the MultiLoc appeared.
7744
7745
<p>This problem has been corrected: the room description generator
7746
now ensures that a MultiLoc's contents appear only once.  To do this,
7747
the room description code now excludes each object that is also
7748
located in the "local" top-level room <i>or</i> in any connected
7749
remote room whose contents listing has already been generated.
7750
7751
</div>
7752
7753
<!------------------->
7754
<div class=entry>
7755
7756
NestedRoom now overrides roomRemoteActorDesc() to describe the actor
7757
as being in the nested room.  In the past, if the nested room's
7758
location was visible, the nested room deferred to the location to
7759
provide the description.  This produced misleading messages, because
7760
it described the actor as being in the outermost visible room
7761
containing the actor - which was technically true, but left out the
7762
important information about the intermediate nested room.
7763
7764
</div>
7765
7766
<!------------------->
7767
<div class=entry>
7768
7769
Noise and Odor objects no longer include themselves in LISTEN TO ALL
7770
and SMELL ALL, respectively.  These objects formerly did include
7771
themselves in ALL for these commands, since the commands are
7772
obviously highly applicable.  However, because these objects are
7773
intangible, it usually doesn't make sense from the player's
7774
perspective to consider them in ALL, which a player usually thinks of
7775
as applying to the set of discrete, visible objects.  In practice,
7776
including these in ALL was often problematic because these intangible
7777
objects are usually not given names or vocabulary; they usually exist
7778
only to model a feature of their source object, and aren't meant to
7779
look like separate objects to the player.
7780
7781
<p>Along the same lines, Vaporous objects <i>are</i> now included in
7782
EXAMINE ALL, SMELL ALL, and LISTEN TO ALL.  These objects do have a
7783
visible presence, so it makes sense to include them in commands that
7784
examine everything in sight with any sense.
7785
7786
<p>For particular Noise and Odor objects that you do want to
7787
participate in LISTEN TO ALL and SMELL ALL, just override
7788
hideFromAll() to return true for the desired action or actions.
7789
7790
</div>
7791
7792
<!------------------->
7793
<div class=entry>
7794
7795
NonPortable now overrides the inherited Thing verify() handling for
7796
EXAMINE to make an un-held NonPortable as likely as a held Thing for
7797
disambiguation purposes.
7798
7799
<p>Recall that, by default, Thing downgrades the disambiguation
7800
likelihood that EXAMINE refers to an object not being held.  The
7801
reasoning is that an object being held is physically closer to the
7802
actor, so in a real-world situation, it would be more convenient to
7803
closely inspect an object being held than one sitting nearby.  Since
7804
NonPortable objects can't be held, though, this reasoning breaks down
7805
somewhat.  The change removes the disambiguation disadvantage for
7806
NonPortable objects.
7807
7808
</div>
7809
7810
<!------------------->
7811
<div class=entry>
7812
7813
The objHeld precondition uses a new Thing method,
7814
meetsObjHeld(actor), to determine if the object meets the condition.
7815
This new method is called instead of isHeldBy(actor) on the given
7816
object.  This change allows an object to indicate that it's not
7817
<i>actually</i> being held by an actor, but that it's as good as held
7818
for the purposes of the objHeld condition.  It's rare for
7819
meetsObjHeld() to return anything other than isHeldBy(), but does
7820
happen occasionally.  The most obvious case is body parts: these
7821
can't be considered to be held in the actor's hands (unless the actor
7822
is specifically doing so for some reason), but at the same time,
7823
there's no reason the actor should have to hold a body part in order
7824
to carry out actions with objHeld conditions.
7825
7826
</div>
7827
7828
<!------------------->
7829
<div class=entry>
7830
7831
The Wearable class now handles SHOW TO specially: if the object is
7832
being worn by the actor doing the showing, it doesn't require that it
7833
be held.  In the past, the objHeld condition was applied, as it is by
7834
default to any portable object, which meant that the character had to
7835
take off a wearable in order to show it to someone; this doesn't usually
7836
make a lot of sense, thus the change.
7837
7838
</div>
7839
7840
<!------------------->
7841
<div class=entry>
7842
7843
In Thing, remoteSpecialDesc(pov) now calls distantSpecialDesc by
7844
default; distantSpecialDesc in turn calls specialDesc by default.  In
7845
the past, remoteSpecialDesc called specialDesc directly by default.
7846
This change leaves the default behavior the same as before, but it
7847
simplifies the common case where the "distant" and "remote"
7848
descriptions are the same by letting a single override -
7849
distantSpecialDesc - handle both descriptions.
7850
7851
<p>Similarly, remoteInitSpecialDesc(pov) now calls
7852
distantInitSpecialDesc by default (rather than initSpecialDesc, as it
7853
did in the past).
7854
7855
</div>
7856
7857
<!------------------->
7858
<div class=entry>
7859
7860
Room now treats the GetOutOf action as equivalent to Out.  (This
7861
means that if the room has vocabulary, the player can now say "get
7862
out of (room)" as a synonym for "out".)
7863
7864
</div>
7865
7866
<!------------------->
7867
<div class=entry>
7868
7869
The English verb grammar now accepts LEAVE as a synonym for EXIT.
7870
7871
</div>
7872
7873
<!------------------->
7874
<div class=entry>
7875
7876
The English parser now accepts "A" and "T" as abbreviations for ASK
7877
and TELL, respectively, in the full phrasing with ABOUT.  That is,
7878
you can now say, for example, A BOB ABOUT BOOK.  In the past, the A
7879
and T abbreviations could only be used in the super-short forms of
7880
the commands, where only the topic could be specified (as in T BOOK).
7881
7882
</div>
7883
7884
<!------------------->
7885
<div class=entry>
7886
7887
The English parser now accepts the formats ASK <i>actor</i> TO
7888
<i>command</i> and TELL <i>actor</i> TO <i>command</i> as equivalent
7889
to the traditional <i>actor</i>, <i>command</i> format for telling an
7890
actor to do something.  The new ASK TO and TELL TO formats are simply
7891
syntactic variations; they're otherwise handled exactly the same way
7892
as the traditional <i>actor</i>, <i>command</i> format.
7893
7894
</div>
7895
7896
<!------------------->
7897
<div class=entry>
7898
7899
In the English library, SpecialTopic now allows a variation on the
7900
input format to accommodate players who are thinking in terms of
7901
ASK/TELL.  Now, when a SpecialTopic is active, and the player's input
7902
<i>doesn't</i> match the special topic's input pattern, <i>and</i>
7903
the user's input starts with "A" or "T" as a separate word, the
7904
SpecialTopic checks for a match to the rest of the player's input
7905
(i.e., the part following the "A" or "T").  For example, if the
7906
special topic is "apologize for forgetting the anniversary," and the
7907
player types T ANNIVERSARY, the special topic will try dropping the
7908
"T" and matching just the "ANNIVERSARY" part.
7909
7910
<p>This change is designed to accommodate players who are accustomed
7911
to the standard ASK/TELL format, and who might not realize that the
7912
special topic list shows commands meant to be entered literally, or
7913
who are just so in the habit of using ASK/TELL commands that it
7914
doesn't occur to them to leave out the "A" or "T" part.  Since an "A"
7915
or "T" command pretty clearly indicates that the player's intent is
7916
to communicate with the NPC, it makes sense to check the topic the
7917
player is trying against any active special topics.
7918
7919
<p>Note that the special topic parser only accepts the
7920
super-abbreviated formats - the "A" and "T" commands.  This is
7921
because it seems much less likely that it would even occur to a
7922
player to try a special command with the full ASK ABOUT or TELL ABOUT
7923
phrasing.  Once the command is expanded to the full phrasing, the
7924
detailed syntax of the special command suggestions should make it
7925
fairly obvious to the player that the ASK ABOUT or TELL ABOUT part
7926
isn't needed.  In contrast, since the abbreviated "A" and "T" formats
7927
are ungrammatical to start with, it would seem perfectly natural to
7928
use them with arbitrary special command suggestions.
7929
7930
</div>
7931
7932
<!------------------->
7933
<div class=entry>
7934
7935
The RoomPart class now downgrades its logicalness for Examine
7936
commands, in the same way that Decoration does.  Room parts are
7937
generally so much background noise, included only in case a player
7938
explicitly refers to them.  Downgrading the logicalness helps prevent
7939
the room parts from causing nuisance disambiguation questions.
7940
7941
</div>
7942
7943
<!------------------->
7944
<div class=entry>
7945
7946
Due to a parser bug, the phrase ALL IN <i>container</i> (which can
7947
also be written ALL FROM, ALL THAT'S IN, etc) incorrectly ignored the
7948
hideFromAll() status of the objects in the container when determining
7949
which objects to match to the phrase.  This has been corrected; the
7950
phrase now respects the hideFromAll() settings of the objects
7951
involved.
7952
7953
</div>
7954
7955
<!------------------->
7956
<div class=entry>
7957
7958
The English parser now matches words it has parsed as "literal
7959
adjectives" to ordinary adjectives in the dictionary when resolving a
7960
phrase in "global scope."  This change is the literal-adjective
7961
equivalent of the <a href='#global_scope_noun_adj'>similar changes</a>
7962
involving noun phrases in global scope introduced in 3.0.6p.
7963
7964
</div>
7965
7966
<!------------------->
7967
<div class=entry>
7968
7969
Noun phrases that consist entirely of a "literal adjective" word are
7970
now marked as "adjective-ending" phrases for the purposes of ranking
7971
grammatical pattern matches during parsing.  (The omission of this
7972
flagging in the past was an oversight.)
7973
7974
</div>
7975
7976
<!------------------->
7977
<div class=entry>
7978
7979
Due to a bug, the removeEvent() method of the RealTimeEvent class
7980
(the common base class for real-time fuses and daemons) didn't work
7981
properly.  This has been corrected.
7982
7983
</div>
7984
7985
<!------------------->
7986
<div class=entry>
7987
7988
A bug in the Lister class caused in-line contents listings to use the
7989
"long list" format (i.e., with semicolons as the separator between
7990
items) if the enclosing list did.  An in-line contents list is set off
7991
by parentheses, so it stands as an independent list and thus should a
7992
long-list format only if it would need to on its own, irrespective of
7993
the needs of the enclosing main list.  (At least, the parentheses are
7994
used in the English library; other languages might use different
7995
notation, but in any case should use a notation that makes the
7996
contents list similarly independent of the enclosing list.)
7997
7998
</div>
7999
8000
<!------------------->
8001
<div class=entry>
8002
8003
A couple of minor changes to the default LOOK IN handling make it
8004
a little easier to customize the behavior, and reduce the need to do
8005
so.
8006
8007
<p>First, Thing has a new property, lookInDesc, that gives a message
8008
that's displayed by default in response to LOOK IN and SEARCH.  This
8009
shows the standard default ("there's nothing unusual in it") if you
8010
don't provide a custom message.  It happens frequently that a game
8011
wants to depict an object as having some interior features, but
8012
doesn't want to actually model those interior features as separate
8013
objects.  The new lookInDesc makes this more convenient, since you
8014
only need to provide the custom message in this property, rather than
8015
overriding the entire dobjFor(LookIn) handling, as was necessary in
8016
the past.
8017
8018
<p>Second, Decoration now treats LOOK IN as logical by default (in the
8019
past, this was handled by the catch-all routine that makes most
8020
actions respond that the object is "not important"), and applies the
8021
same logical-rank downgrade applied to EXAMINE.  Correspondingly,
8022
the default lookInDesc for Decoration displays the object's "not
8023
important" message.  This means that Decoration objects act by
8024
default as they did before, displaying "that isn't important" in
8025
response to LOOK IN, but can be given a custom LOOK IN response
8026
simply by setting lookInDesc, just as with any Thing.
8027
8028
<p>Third, the English phrasing for finding nothing in an object
8029
specifically searched with LOOK IN or SEARCH has changed slightly, to
8030
report that there's nothing "unusual" in the object.  In many cases,
8031
an object is described as having what would in the real world be
8032
interior features, but those interior features aren't modeled as
8033
actual game objects and hence don't show up by default in response to
8034
LOOK IN or SEARCH.  The slight change in phrasing helps make the
8035
response at least technically defensible.  It's probably still better
8036
in most cases to customize the LOOK IN response anyway, but at least
8037
the default response is a little less jarring in these cases.
8038
8039
</div>
8040
8041
<!------------------->
8042
<div class=entry>
8043
8044
Decoration now treats READ as logical by default, the same as it
8045
does EXAMINE.  (As mentioned above, LOOK IN now has the same treatment
8046
as well.)
8047
8048
</div>
8049
8050
<!------------------->
8051
<div class=entry>
8052
8053
In the Thing class, PUT X IN X and PUT X ON X now respond with custom
8054
messages ("you can't put the X in/on itself").  In the past, the
8055
catch-all message indicating that X isn't a container/surface was
8056
used, which is a less conspicuous problem than attempting to put
8057
something in or on itself.
8058
8059
</div>
8060
8061
<!------------------->
8062
<div class=entry>
8063
8064
In the English library, the 
8065
<a href='#pluralToNounExpansion'>plural-to-noun match expansion</a>
8066
introduced in version 3.0.6p is now limited to "global scope," just as the
8067
<a href='#nounEndingToAdjEndingExpansion'>noun-ending-to-adjective-ending
8068
match expansion</a> already was.  English plurals are usually formed
8069
by adding "s" or "es" to the end of a word, so when a noun is six
8070
letters or longer, it usually looks like a truncated form of its plural;
8071
this interacted with the plural-to-noun match expansion to be overly
8072
aggressive in upgrading phrases to a plural interpretation.  The
8073
match expansion is only really important in global scope anyway (for
8074
the reasons why, see the explanation of the 
8075
<a href='#nounEndingToAdjEndingExpansion'>noun-to-adjective expansion</a>),
8076
so this change maintains the primary benefits of the match expansion
8077
while avoiding the weird cases that can come up in local scope.
8078
8079
</div>
8080
8081
<!------------------->
8082
<div class=entry>
8083
8084
The parser now considers an indefinite noun phrase to be less
8085
desirable, for grammar selection purposes, than a definite
8086
interpretation of the same phrase.  Object names can occasionally look
8087
like indefinite phrases: an elevator button labeled "1" could be
8088
called a "one button," for example, and a subway might have an "A
8089
train."  When there's an interpretation that exactly matches the
8090
phrase to the name of an in-scope object, the parser will now prefer
8091
that interpretation over one that treats a word like "a" or "one" as
8092
signifying that an arbitrary match to the other words should be
8093
chosen.
8094
8095
</div>
8096
8097
<!------------------->
8098
<div class=entry>
8099
8100
A library bug that caused a run-time error in
8101
Actor.findVisualObstructor() has been corrected.
8102
8103
</div>
8104
8105
<!------------------->
8106
<div class=entry>
8107
8108
The library now executes "prompt daemons" (the special type of daemon
8109
that runs before each command prompt, rather than when the turn
8110
counter changes) before <i>every</i> prompt, rather than just before
8111
a main command prompt.  This ensures that various miscellaneous tasks
8112
are performed whenever the game pauses for user input, even when
8113
input is requested in the course of processing a command.
8114
8115
</div>
8116
8117
<!------------------------------- 3.0.6p --------------------------------->
8118
<div class="sepbar"><a name='306p'></a>3.0.6p</div>
8119
<p><b><i>Released 4/25/2004</i></b>
8120
<p>
8121
8122
<div class=firstentry>
8123
8124
<b>Compatibility-breaking change:</b> The property initDesc, and the
8125
related properties, have been <b>renamed</b>.  Games that define or
8126
use these properties will have to change to use the new names.  You
8127
should search all of your existing source for the old names, and
8128
replace each one with the corresponding new name.
8129
8130
<p><b>Important:</b> you <b>must</b> search for "initDesc" and
8131
replace it with "initSpecialDesc" <b>first</b>.  This is required
8132
because the former "initExamineDesc" has been renamed to "initDesc" -
8133
so you have to make sure you change all the old "initDesc" instances
8134
<b>before</b> you rename "initSpecialDesc" to create new "initDesc"
8135
instances.  Please do your search-and-replace operations in the order
8136
shown below:
8137
8138
<ul>
8139
<li>change "initDesc" to "initSpecialDesc"
8140
<li>change "useInitDesc" to "useInitSpecialDesc"
8141
<li>change "obscuredInitDesc" to "obscuredInitSpecialDesc"
8142
<li>change "distantInitDesc" to "distantInitSpecialDesc"
8143
<li>change "initExamineDesc" to "initDesc"
8144
<li>change "useInitExamineDesc" to "useInitDesc"
8145
</ul>
8146
8147
<p>The purpose of this change is to make the naming more consistent.
8148
The old usage - "initDesc" for a special description and
8149
"initExamineDesc" for the EXAMINE description - was inconsistent with
8150
the respective non-initial properties, "specialDesc" and "desc".  The
8151
qualification was reversed: "specialDesc" was qualified as special,
8152
leaving the EXAMINE description unqualified as simply "desc", while
8153
the initial descriptions qualified the EXAMINE desription rather than
8154
the special one.
8155
8156
</div>
8157
8158
<!------------------->
8159
<div class=entry>
8160
8161
<b>Minor compatibility-breaking change:</b> The Attachable class's
8162
scheme for explaining why the object can't be attached to a given
8163
other object has been changed.  In the past, the method
8164
cannotAttachMsg(obj) returned a message string or
8165
actor-action-messages property, but this created a conflict with
8166
another message property of the same name, which is used by Thing.  To
8167
resolve the conflict, the Attachable method has now been renamed to
8168
explainCannotAttachTo(obj), and rather than returning a message to
8169
display, the new method simply displays the message itself.
8170
8171
<p>If you have any Attachable objects that define cannotAttachMsg,
8172
you must make two changes to each.  First, rename cannotAttachMsg
8173
to explainCannotAttachTo.  Second, rather than returning a string,
8174
display the string directly.
8175
8176
</div>
8177
8178
<!------------------->
8179
<div class=entry>
8180
8181
<b>Possible compatibility-breaking change:</b> The conversation
8182
mechanism has some internal changes to support deferral across
8183
hierarchy levels (<a href='#topicDeferral'>see below</a>).
8184
8185
<ul>
8186
8187
<li>In TopicDatabase.<b>findTopicResponse()</b>, the former first
8188
parameter, 'topicList', has been dropped, and two new parameters have
8189
been added: 'convType', giving the conversation action type; and
8190
'path', giving a list of the inferior topic databases that will be
8191
searched for the topic if it's not found in the current database
8192
(i.e., 'self').
8193
8194
<li>In TopicDatabase.<b>handleTopic()</b>, the former first parameter,
8195
'topicList', has been dropped; and two new parameters have been added:
8196
'convType' and 'path'.  These have the same meanings as above.
8197
8198
<li>In ConvNode.<b>handleConversation()</b>, the new parameter 'path'
8199
has been added.  This <b>only</b> affects the ConvNode instance of
8200
this method - the method of the same name in Actor and ActorState is
8201
unchanged.
8202
8203
</ul>
8204
8205
<p>Note that the TopicDatabase methods findTopicResponse() and
8206
handleTopic() no longer need the topic list parameter because this
8207
information can be obtained from the new convType parameter.
8208
8209
<p>These methods are mostly for internal use by the library, so the
8210
likelihood that your existing game code will be affected is small.
8211
Even so, you should scan through your code for these methods and make
8212
the appropriate adjustments.  
8213
8214
<p><b>Important:</b> note that there are two related but independent
8215
methods called handleTopic().  There's the TopicDatabase method,
8216
which <b>is</b> affected by this change, and there's the separate
8217
TopicEntry method, which is <b>not</b> affected.  When you're
8218
scanning your code, you only need to change the TopicDatabase
8219
version.  It's easy to tell which is which at a glance: the
8220
TopicDatabase version takes <b>three</b> parameters, while the
8221
TopicEntry version only takes <b>two</b>.  When you're scanning your
8222
code, <b>only change the three-parameter instances</b>.
8223
8224
<p><b>Additional technical notes:</b> you'll only need to read this
8225
part if you're making some rather advanced overrides to the library.
8226
Please skip this part unless you find something that you're not sure
8227
how to handle in the search-and-replace step above.
8228
8229
<p>If your code contains calls to any of the affected methods, and
8230
you're wondering what to pass for the convType parameter, you should
8231
first check to see if you're receiving that value as a parameter to
8232
the calling code; if so, just pass that parameter down.  This is
8233
usually easy to spot at a glance.  If you have code like this:
8234
8235
<p><pre>
8236
   handleTopic(<b>self.(convType.topicListProp)</b>, actor, topic);
8237
</pre>
8238
8239
<p>then you can simply change it to this:
8240
8241
<p><pre>
8242
   handleTopic(actor, topic, <b>convType</b>, nil);
8243
</pre>
8244
8245
<p>The important thing to note here is that you're already using the
8246
convType parameter to look up the topic list in the old-style call;
8247
you can simply drop the topic list lookup and pass the convType
8248
parameter itself instead (but note that it moves to the last
8249
position).
8250
8251
<p>If you don't have a convType parameter passed in from your caller,
8252
you'll need to choose which one to use.  Look at which topic list
8253
you're passing, and think about what conversational action is
8254
triggering your code.  Then scan through the list of xxxConvType
8255
objects (askAboutConvType, tellAboutConvType, yesConvType,
8256
noConvType, etc) defined in actor.t, and choose one that (1) has the
8257
same topic list property that you're already using, defined in its
8258
topicListProp property, and (2) conceptually matches the action
8259
you're performing.  If you can't find anything appropriate, you might
8260
simply need to define your own ConvType object for whatever extended
8261
action you're defining; just create one following the same pattern
8262
as the existing ones in actor.t.
8263
8264
<p>You can usually just pass nil for the new fourth parameter ('path')
8265
to handleTopic(), findTopicResponse(), and
8266
ConvNode.handleConversation().  You only have to pass a non-nil value
8267
when you're implementing a search through a hierarchy of topic
8268
databases, in which case you'll have to pass a list of the inferior
8269
databases in the hierarchy.  The purpose of the new parameter is to
8270
allow a higher-level database to defer to a match in a lower-level
8271
database, if one exists, so at each level you must pass the remainder
8272
of the "search path" of databases.
8273
8274
</div>
8275
8276
<!------------------->
8277
<div class=entry>
8278
8279
<a name='topicDeferral'></a>
8280
The above changes to the conversation methods are designed to
8281
facilitate a new mechanism that allows a conversation TopicEntry in
8282
one topic database to defer to a TopicEntry from an inferior
8283
database.  This is done through the new TopicEntry method
8284
deferToEntry(entry): this method returns true if 'self' should defer
8285
to 'entry', nil if not.  'entry' is always a non-nil TopicEntry
8286
object from an inferior topic database.
8287
8288
<p>Recall that topic entry databases for conversation are arranged
8289
into a three-level hierarchy for each actor: at the top is the
8290
ConvNode's list of topics, at the middle level is the ActorState
8291
list, and at the bottom level is the Actor list.  We find a matching
8292
topic entry by scanning each level of this hierarchy in turn, and
8293
taking the first match we find.  So, if there's a ConvNode match for
8294
a topic we're looking for, we use it, even if there's a match for the
8295
same topic in the ActorState or Actor.  The matchScore is irrelevant:
8296
the three-level hierarchy always trumps the matchScore ranking.  The
8297
matchScore ranking is only used to choose among different matching
8298
entries <i>at the same hierarchy level</i>.
8299
8300
<p>The new deferToEntry() mechanism allows topic entries to defer
8301
handling across hierarchy levels.  Here's how the new scheme works:
8302
before we start searching the hierarchy, we start by noting the
8303
matching entry at each level.  Then, we search each level from the
8304
top down as before.  At each level, though, we look at the winning
8305
match, and ask it via deferToEntry() if it wants to defer to the
8306
winning match from the next level down the hierarchy.  If so, then
8307
we ignore the match at that level.  This means that we skip the
8308
higher-level match and go straight to the lower-level handling.
8309
8310
<p>The main purpose of this addition is to allow a DefaultTopic
8311
entry to be a catch-all only for topics that aren't handled
8312
explicitly at a lower hierarchy level.  For example, to create a
8313
DefaultTopic that defers to any non-default match at a lower
8314
hierarchy level, add this to the DefaultTopic object:
8315
8316
<p><pre>
8317
   deferToEntry(other) { return !other.ofKind(DefaultTopic); }
8318
</pre>
8319
8320
<p>This tells the topic finder that if there's any match that's
8321
not itself a DefaultTopic at a lower hierarchy level, then this
8322
default should be ignored.
8323
8324
</div>
8325
8326
<!------------------->
8327
<div class=entry>
8328
8329
The English library template for Room has been extended, and the
8330
default relationships that derive one type of Room naming property
8331
from another have changed slightly.  These changes should be fully
8332
compatible with existing game code, and should make it easier
8333
to customize the various kinds of room names.
8334
8335
<p>The template for Room now takes the first string to be the
8336
'roomName' property, the second to be 'destName', and the third to be
8337
the 'name' property.  The 'desc' property is still in the last
8338
position.
8339
8340
<p><pre>
8341
  Room template 'roomName' 'destName'? 'name'? "desc"?;
8342
</pre>
8343
8344
<p>In the past, the 'name' was the first entry, and 'destName' was
8345
the second.  The library took the 'roomName' to be the same as the
8346
'name'.  However, it makes more sense to do this the other way
8347
around: the 'roomName' is now the one that's explicitly defined by
8348
the game, and the 'name' setting is optional.  If the 'name' setting
8349
is omitted, it's derived by default by converting the 'roomName' to
8350
lower case.
8351
8352
<p>The 'roomName' is what's shown as the title of the room, in the
8353
room description and on the status line.  This is usually given in
8354
"title case," meaning that each word has an initial capital letter,
8355
with the exception of minor function words: "Hall of the Ancient
8356
Kings".  This is the format that games have defined all along, but
8357
in the past, they defined it using the 'name' property.  The change
8358
improves matters, because it allows the room's ordinary 'name'
8359
property to be entered separately, in a format suitable for use
8360
when the name is needed in library messages: "You can't have the
8361
ice cave."
8362
8363
<p>The default 'name' derivation - converting the 'roomName' string
8364
to lower case - gives decent results a lot of the time.  However, in
8365
many cases, you'll want to customize the ordinary name separately.
8366
The template makes this easy by adding a slot for the 'name' property
8367
separately from the 'roomName'.
8368
8369
<p>There's one additional change to the default derivations.  In the
8370
past, the 'destName' didn't have a default at all.  Now, the default
8371
is the room's 'theName', which is itself derived, by default, by 
8372
prepending the ordinary name with 'the'.  As before, the template
8373
lets you supply a separate, custom 'destName' value.
8374
8375
</div>
8376
8377
<!------------------->
8378
<div class=entry>
8379
8380
The MultiLoc object now transmits sense information to and from
8381
its contents in a more consistent fashion.  In the past, putting
8382
things inside a MultiLoc had somewhat inconsistent results; the
8383
behavior should be more predictable now.
8384
8385
<p>The primary design principle of a MultiLoc hasn't changed: a
8386
MultiLoc is a single object that appears in multiple locations, but
8387
which doesn't provide any sense connection among the multiple
8388
containers.  A MultiLoc is a <i>single</i> object in the sense that
8389
the same object appears, in its physical entirety, in each of its
8390
containers.
8391
8392
<p>In the past, a MultiLoc was essentially a "sense ceiling": sense
8393
information propagated from outside the MultiLoc to its interior, but
8394
didn't propagate from within the MultiLoc to its containers.  This was
8395
intended to prevent the MultiLoc from propagating sense information
8396
among its containers, but it was too restrictive an implementation.
8397
For example, if a MultiLoc contained a flashlight, the flashlight's
8398
light didn't shine into the MultiLoc's locations.  Similarly, if an
8399
NPC was inside a MultiLoc, the NPC couldn't see or hear anything from
8400
any of the MultiLoc's locations, and hence couldn't take part in a
8401
conversation with the PC while the PC was outside the MultiLoc.
8402
8403
<p>The change is that a MultiLoc is no longer a sense ceiling; it's
8404
now more like a wall.  Now, from a point of view inside the MultiLoc,
8405
all of the MultiLoc's locations (and their contents, to the extent
8406
that's appropriate) are visible.  From the point of view of any of
8407
the MultiLoc's containers, the MultiLoc and its contents (as
8408
appropriate) are visible, but none of the MultiLoc's other containers
8409
are visible.  Light is similarly transmitted from inside the MultiLoc
8410
to all of its containers, but not from one container to another.  So,
8411
for example, if a flashlight is inside a MultiLoc, it provides light
8412
to every container of the MultiLoc; but if a flashlight is in one of
8413
a MultiLoc's containers, the light doesn't make it through the
8414
MultiLoc to its other containers.
8415
8416
<p>The main effect of this change is that things located inside a
8417
MultiLoc now behave the way one would expect them to.  In the past,
8418
the asymmetrical "sense ceiling" design led to some odd behavior when
8419
putting objects inside a MultiLoc: an actor within a MultiLoc
8420
couldn't carry on a conversation with someone outside, for example,
8421
because the actor inside couldn't hear out beyond the MultiLoc.
8422
With the change, MultiLoc should behave much more intuitively.
8423
8424
</div>
8425
8426
<!------------------->
8427
<div class=entry>
8428
8429
The ContainerDoor class now defines the isOpen method to return the
8430
same thing as its associated container's isOpen method; and it now
8431
defines examineStatus to display its associated container's
8432
open/closed status.
8433
8434
</div>
8435
8436
<!------------------->
8437
<div class=entry>
8438
8439
A ComplexContainer can now be used as a bag of holding.  Operations
8440
involving the bag-of-holding features of a complex container are
8441
simply passed redirected to the complex container's subContainer
8442
object.
8443
8444
</div>
8445
8446
<!------------------->
8447
<div class=entry>
8448
8449
Certain object contents listings were grammatically incorrect when
8450
showing a single item that had a plural name.  For example, if an item
8451
had the name "some coins," and it was the only item on a table, the
8452
table description said "On the table is some coins."
8453
8454
<p>The listers now take into account the "cardinality" of each item
8455
listed, to ensure grammatical agreement in these cases.  For English,
8456
there are only two degrees of cardinality that matter: one, and many.
8457
The English module therefore assigns a grammatical cardinality of 2 to
8458
items whose isPlural property is set to true, 1 for all others; this
8459
is done with the new Thing method listCardinality(lister).  A lister
8460
calls this new method to determine the cardinality of the list, so
8461
that it can provide the correct information to the methods that
8462
generate the messages.
8463
8464
</div>
8465
8466
<!------------------->
8467
<div class=entry>
8468
8469
The LISTEN TO command now lists not only the sound the object being
8470
examined is making, but the audible sounds of its contents as well.
8471
This ensures that sounds made by components of an object are properly
8472
displayed when the enclosing object is examined, and also ensures that
8473
a container that has a sound source inside will have its sound listed.
8474
8475
<p>The SMELL command has been similarly enhanced.
8476
8477
<p>As part of this change, the thingListenDesc and thingSmellDesc
8478
messages have been moved from libMessages to playerActionMessages, and
8479
renamed thingListenDescMsg and thingSmellDescMsg, respectively.  These
8480
messages are now shown as default description messages, necessitating
8481
the move to playerActionMessages.
8482
8483
</div>
8484
8485
<!------------------->
8486
<div class=entry>
8487
8488
The Distant class now explicitly allows LISTEN TO, the same way
8489
it allows EXAMINE.
8490
8491
</div>
8492
8493
<!------------------->
8494
<div class=entry>
8495
8496
It's now possible to create a SenseConnector that occludes some
8497
objects from view, depending on the point of view.  This is useful
8498
for situations where a sense connector provides only a partial view
8499
of another room.  For example, consider two rooms with a window
8500
between them, providing a view of one room from the other.  Now,
8501
suppose a bookcase is positioned with its back to the window.  When
8502
viewing the room with the bookcase from the other side of the window,
8503
it's not possible to see the contents of the bookcase.
8504
8505
<p>The new class, OccludingConnector, is a mix-in that you can
8506
combine with SenseConnector to create a partially occluded sense
8507
path.  Put OccludingConnector before SenseConnector in the class
8508
list.  You specify which objects to occlude from view by defining the
8509
method occludeObj(obj, sense, pov).  'obj' is an object to test for
8510
occlusion; 'sense' is the sense being calculated; and 'pov' is the
8511
point of view, which is usually the actor performing the command.
8512
Your method must return true if the connector occludes the object,
8513
nil if not.
8514
8515
<p>To implement the window in our example above, we'd do something
8516
like this:
8517
8518
<p><pre>
8519
  OccludingConnector, SenseConnector, Fixture 'window' 'window'
8520
    "It's a small window. "
8521
    connectorMaterial = glass
8522
    locationList = [roomA, roomB]
8523
    occludeObj(obj, sense, pov)
8524
    {
8525
      /* from roomA, we can't see what's in the bookcase in roomB */
8526
      return (pov.isIn(roomA) &amp;&amp; obj.isIn(bookcase));
8527
    }
8528
  ;
8529
</pre>
8530
8531
</div>
8532
8533
<!------------------->
8534
<div class=entry>
8535
8536
<p>OccludingConnector uses a new mechanism that can be used for more
8537
extensive customization of the sense path calculation than
8538
OccludingConnector itself enables.  During each sense path
8539
calculation, the library first builds a table of all of the objects
8540
connected by containment to the point of view.  (This table contains
8541
all of the objects that can possibly be sensed, because sense paths
8542
are based entirely on containment relationships.)  The library then
8543
calls clearSenseInfo() on each item to initialize it for the path
8544
calculation.
8545
8546
<p>In clearSenseInfo(), an object can register itself for an
8547
additional notification at the end of the sense calculation.  To
8548
register for the notification, override clearSenseInfo(), inherit the
8549
default code, and append 'self' to the notification vector:
8550
8551
<p><pre>
8552
  clearSenseInfo()
8553
  {
8554
    inherited();
8555
    senseTmp.notifyList.append(self);
8556
  }
8557
</pre>
8558
8559
<p>Now that the object is registered, it will be notified at the
8560
end of the calculation, after the sense path to each object is fully
8561
calculated, but before the final table of sense paths is constructed.
8562
The notification method is called finishSensePath(objs, sense).  'objs'
8563
is a LookupTable whose keys are the objects connected by containment
8564
to the point of view; 'sense' is the Sense object of the calculation.
8565
8566
<p>You can do anything you want to the sense table in
8567
finishSensePath().  The sense path information for each object is
8568
stored in the object's tmpXxx_ properties - tmpTrans_, tmpAmbient_,
8569
tmpObstructor_, etc.  To change an object's sense path, simply change
8570
those properties.  (OccludingConnector simply sets each occluded
8571
object's path transparency, in tmpTrans_ and tmpTransWithin_, to nil
8572
to indicate that the object cannot be seen.)  You can make additional
8573
objects visible by adding them to the lookup table and setting their
8574
tmpXxx_ properties to the settings you want them to have.
8575
8576
<p>Note that the notification step is required for performance
8577
reasons.  The library <i>could</i> call the notification method on
8578
every object, which would simplify things by eliminating the need for
8579
the extra line of code to register.  However, very few objects are
8580
likely to require this extra notification, and since sense path
8581
calculations are performed very frequently, the library doesn't want
8582
to call the notification method blindly on all objects.  So, to avoid
8583
adding the notification overhead to every object, the library
8584
requires the rare objects that require the notification to register
8585
themselves.
8586
8587
</div>
8588
8589
<!------------------->
8590
<div class=entry>
8591
8592
The logic that decides on the descriptions generated for distant and
8593
obscured objects has changed slightly.  The purpose of these changes
8594
is to make it easier to customize the various ways an object is
8595
described, and to make the selection of description more intuitive.
8596
8597
<p>First, a new type of description has been added: the "remote"
8598
description.  There are three new remote description methods:
8599
remoteDesc, for the EXAMINE description; remoteSpecialDesc, for the
8600
special description; and remoteInitSpecialDesc, for the remote
8601
initial special description.  These new methods are used to provide
8602
the examination and special descriptions when the object is viewed
8603
from a separate top-level location.  For example, if two top-level
8604
rooms are connected by a window, so that an actor in one room can see
8605
objects in the other room through the window, the remote description
8606
is used to describe objects in the other room from the actor's
8607
perspective.
8608
8609
<p>Second, when choosing a special description (as part of a room or
8610
contents listing), the logic is now as follows:
8611
8612
<ul>
8613
<li>If the object is in a separate top-level location from the actor
8614
doing the looking, the remoteSpecialDesc is shown;
8615
<li>otherwise, if the object is obscured, the obscuredSpecialDesc is shown;
8616
<li>otherwise, if the object is distant, the distantSpecialDesc is shown;
8617
<li>otherwise, the specialDesc is shown.
8618
</ul>
8619
8620
<p>In the past, the sightSize was taken into account in selecting the
8621
type of special description to show: the specialDesc was shown if the
8622
object had a large visual size, regardless of the transparency of the
8623
sense path.  Now, the sightSize isn't considered at all.  The reason
8624
for the change is that the distantDesc and obscuredDesc are almost
8625
always custom messages per object, so they will naturally take into
8626
account the visual size of the object; considering the visual size
8627
added an unnecessary extra dimension.
8628
8629
<p>Note how the new remoteSpecialDesc fits into the selection rules:
8630
the remote special description takes precedence over the obscured and
8631
distant descriptions.  That is, if the object being described is in a
8632
separate top-level room from the actor doing the looking, the
8633
remoteSpecialDesc is used, even if the object is <i>also</i> visually
8634
obscured or at a distance.
8635
8636
<p>Third, when choosing an examine description (when the object is
8637
explicitly examined), the logic is now as follows:
8638
8639
<ul>
8640
<li>If the object is in a separate top-level room from the actor
8641
doing the looking, <b>and</b> a remoteDesc method is defined for
8642
the object, the remoteDesc method is used;
8643
<li>otherwise, if the object is obscured, <b>and</b> an obscuredDesc 
8644
method is defined for the object, the obscuredDesc method is used;
8645
<li>otherwise, if the object is distant, <b>and</b> a distantDesc method
8646
is defined for the object, the distantDesc method is used;
8647
<li>otherwise, if the object's details are visible (which will be true
8648
even for a distant or obscured object with sightSize set to large), the
8649
ordinary desc is used;
8650
<li>otherwise, if the object is obscured, the defaultObscuredDesc
8651
method will be used;
8652
<li>otherwise, if the object is distant, the defaultDistantDesc
8653
method will be used.
8654
8655
<p>In the past, the 'desc' was used any time the visual details were
8656
visible, even if the object was distant or obscured and even if the
8657
object had a custom distantDesc or obscuredDesc.  The change is that
8658
the distantDesc or obscuredDesc will essentially "override" the
8659
ordinary 'desc' when custom definitions are provided, regardless of
8660
the visual size of the object.  The reason for this change is to keep
8661
the EXAMINE description selection rules consistent with the special
8662
description rules; the rules are essentially parallel in the two
8663
cases.  The EXAMINE selection rules are slightly more complicated
8664
because of the need to generate suitable defaults when a custom
8665
obscured/distant description is not defined: by considering first
8666
whether or not a custom description is available, we can decide to
8667
show the custom distant/obscured description (if one is available),
8668
the default ordinary description (if no custom description is
8669
available <b>and</b> the details are visible), or a default
8670
distant/obscured description (in any other case).
8671
8672
<p>Note that the defaultObscuredDesc and defaultDistantDesc methods
8673
are new.  The default implementations simply display the same default
8674
library messages that the default obscuredDesc and distantDesc
8675
implementations displayed in past versions.
8676
8677
</div>
8678
8679
<!------------------->
8680
<div class=entry>
8681
8682
<p>The logic for deciding whether or not to use the initial special
8683
description and initial examine description for an object has been
8684
refactored slightly.  The refactoring yields the same default effects
8685
as before, so existing game code won't be affected, but the changes
8686
provide better control for overriding the default behavior.
8687
8688
<p>First, the new Thing method isInInitState determines whether or
8689
not to use the initial special and examine descriptions.  By default,
8690
this method returns true if the object has never been moved, nil if
8691
the object has been moved.  That is, the object is considered to be
8692
in its initial state, for the purposes of descriptions, until the
8693
first time the object is moved by an actor in the game.
8694
8695
<p>Second, the new Thing method useInitExamineDesc() indicates
8696
whether or not the initExamineDesc should be used when examining the
8697
object.  By default, this returns true if the object is in its
8698
initial state, as indicated by isInInitState, <b>and</b> the object
8699
defines a non-nil initExamineDesc.  Since isInInitState by default
8700
returns true if the object has never been moved, and nil otherwise,
8701
the default behavior is the same as before, so existing games will
8702
not be affected by this change.
8703
8704
<p>Third, the existing Thing method useInitDesc() looks at
8705
isInInitState to make its determination.  Since isInInitState by
8706
default returns true if the object has never been moved, this has the
8707
same effect as in the past.
8708
8709
<p>These changes make it easier to change the "never moved" logic
8710
that determines whether or not to use initial descriptions, and also
8711
allows you to control the use of the initial special and examine
8712
descriptions independently of one another.  For example, if you want
8713
the initial examine description to be used one time only, rather than
8714
to be based on whether the object has been moved, you could override
8715
useInitExamineDesc() to base its determination on 'described' rather
8716
than on 'moved'.
8717
8718
</div>
8719
8720
<!------------------->
8721
<div class=entry>
8722
8723
In the English library, Room has a new method that provides a
8724
prepositional phrase that can be used to describe objects as being in
8725
the room.  The new method is inRoomName(pov), and it returns a string
8726
that can be used to construct a sentence describing objects as being
8727
in the room.  'pov' is the point of view; this might not be in the
8728
same top-level room, as we could be viewing objects in this room from
8729
the point of view of a separate room that's connected to our room by
8730
a window or another sense connector.
8731
8732
</div>
8733
8734
<!------------------->
8735
<div class=entry>
8736
8737
Room descriptions now include listings of the portable objects
8738
visible in separate top-level locations.  In the past, only the
8739
contents of the point-of-view actor's own enclosing room were
8740
described; now, the contents of each connected top-level room are
8741
described as well.
8742
8743
<p>To generate the new remote room contents listings, the room
8744
describer first determines the set of top-level rooms with items that
8745
are visible from the point of view of the actor doing the looking.
8746
The room describer shows the contents of the local room (the room
8747
containing the point of view) first, using the same procedure it
8748
always has.  Next, the describer runs through the set of other
8749
top-level rooms with visible contents; for each one, it generates a
8750
separate remote contents listing.
8751
8752
<p>Each remote room's contents listing is displayed using essentially
8753
the same procedure used to generate the local room's contents
8754
listing.  However, instead of using the lister defined by the local
8755
room's roomContentsLister property (which is set to the roomLister
8756
object by default), each remote listing is generated using a lister
8757
returned by the new method remoteRoomContentsLister(other).  This
8758
method is called on the point-of-view room, and 'other' is the remote
8759
room whose contents are to be listed.  By default, this returns a
8760
lister that uses the remote room's inRoomName to generate the
8761
description.  
8762
8763
<p>You can customize the listing of portable items visible in remote
8764
locations by returning a custom lister from remoteRoomContentsLister().
8765
Note that the new class CustomRoomLister makes this easy, if all you
8766
want to do is to customize the prefix and suffix messages displayed
8767
in the listing:
8768
8769
<p><pre>
8770
  remoteRoomContentsLister(other)
8771
  {
8772
    return new CustomRoomLister('Through the window, {you/he} see{s}', '.');
8773
  }
8774
</pre>
8775
8776
<p>Note that remoteRoomContentsLister(other) is called on the
8777
<i>local</i> room - the room containing the actor doing the looking -
8778
and 'other' is the <i>remote</i> room.  This arrangement lets you
8779
customize the listing in the point-of-view room, which makes sense in
8780
that the overall description is of the point-of-view room.
8781
8782
</div>
8783
8784
<!------------------->
8785
<div class=entry>
8786
8787
When a room is described (as when entering the room, or examining it
8788
with a LOOK AROUND command), everything visible from the room is
8789
marked as having been seen.  In the past, only visible objects that
8790
were located within the actor's top-level enclosing location were
8791
marked as visible; now, everything that's visible is marked as seen,
8792
including objects in other top-level rooms that are visible from the
8793
actor's location.
8794
8795
</div>
8796
8797
<!------------------->
8798
<div class=entry>
8799
8800
The library has an enhanced way of listing an actor's presence in a
8801
room (as part of the room description) when the actor is visible in a
8802
remote location (i.e., a separate top-level room) or at a distance.
8803
In the past, there was no distinction between the normal case and the
8804
distant and remote cases.  Now, when the actor is in a remote room,
8805
or at a distance, a different path is used to generate the message.
8806
8807
<p>To accomplish this change, Actor now overrides remoteSpecialDesc
8808
and distantSpecialDesc.  On LOOK AROUND, the room calls the
8809
appropriate one of these to describe the actor when the actor is at a
8810
distance.  (The normal selection procedure is used: the
8811
remoteSpecialDesc is used if the NPC is in a separate top-level
8812
location from the point-of-view actor, otherwise distantSpecialDesc
8813
is used if the NPC is at a distance.)  The new Actor implementations
8814
of remoteSpecialDesc and distantSpecialDesc invoke the corresponding
8815
new ActorState methods of the same names.  These new ActorState
8816
methods in turn call back to the new Actor method actorThereDesc
8817
(both the distant and remote methods call this one new method).  The
8818
new actorThereDesc calls the new method roomRemoteActorDesc on
8819
the actor's location.  Thing provides a default
8820
implementation of this new methods, which simply calls the same
8821
thing on its the location if there's a location that's visible from
8822
the point of view, or shows a default library message if not.  The
8823
default library message method is also called roomRemoteActorDesc.
8824
This uses the location's inRoomName to generate the description.
8825
8826
<p>This sequence of calls lets you hook in and customize the actor's
8827
distant special description at whatever level is most convenient -
8828
at the actor itself, at the ActorState, or at the containing room.
8829
In most cases, it will probably be most convenient to customize this
8830
in the room, to display a message customized to the appearance of
8831
the room from a distance.  To do this, you'd put a method like this
8832
on the room:
8833
8834
<p><pre>
8835
  roomRemoteActorDesc(actor)
8836
  {
8837
    "\^&lt;&lt;actor.nameIs&gt;&gt; over at the north end of the courtyard. ";
8838
  }
8839
</pre>
8840
8841
<p>Note that the actor to describe is provided as a parameter, and
8842
that the method is responsible for displaying the complete message
8843
describing the actor's presence.
8844
8845
</div>
8846
8847
<!------------------->
8848
<div class=entry>
8849
8850
In the past, an EXAMINE command applied to a room was always treated
8851
as a LOOK AROUND command; this didn't produce good results when the
8852
room being examined was a separate room that the actor doing the
8853
looking wasn't in (i.e., a room connected to the actor's location via
8854
a sense connector of some kind).  This no longer happens; when the
8855
actor doing the looking isn't inside the room, the standard EXAMINE
8856
handling is used, as though the room were any ordinary object.
8857
8858
</div>
8859
8860
<!------------------->
8861
<div class=entry>
8862
8863
Thing.lookAroundPov() now actually sets a global point-of-view object.
8864
This ensures that the POV information can be obtained (via the getPOV()
8865
function) when room descriptions are being shown.
8866
8867
</div>
8868
8869
<!------------------->
8870
<div class=entry>
8871
8872
Thing.addToSenseInfoTable() no longer includes the 'src' parameter.
8873
Instead, the same information can be obtained from
8874
senseTmp.pointOfView.  (The parameter has been removed for effiency:
8875
the information is rarely needed, and is available from this other
8876
source when it is needed.)
8877
8878
</div>
8879
8880
<!------------------->
8881
<div class=entry>
8882
8883
The Thing method canDetailsBeSensed() now takes an addition parameter
8884
giving the point of view.  This is usually the actor performing a
8885
LOOK AROUND, EXAMINE, or other command that's causing a description
8886
of the object to be generated.
8887
8888
</div>
8889
8890
<!------------------->
8891
<div class=entry>
8892
8893
Thing.lookAroundWithinSense now marks each item with a "presence" in
8894
the sense as known to the actor who's doing the looking.  This
8895
ensures that any noises and odors that are actively listed become
8896
known to the actor as soon as they're listed.  
8897
8898
Objects are marked as known rather than seen, because it might be
8899
possible to hear or smell objects that can't be seen.  Note that only
8900
objects with a "presence" in the sense are marked as known; an object
8901
with a presence in a sense is one that is actively calling attention
8902
to itself in the sense, via a noise or odor message in the room
8903
description.  Thus, an object that isn't actually making any noise
8904
worth listing doesn't become known just because an actor could hear
8905
it if it were making noise; it has to actually be making some noise
8906
(and say so by setting its soundPresence to true) to become known in
8907
this manner.  Note also that a noise and its source are frequently
8908
separate objects (likewise with odors), and it's the <i>noise</i>
8909
that becomes known in this arrangement, not the source.  This is
8910
important because it's often possible to hear the sound a thing makes
8911
without knowing what's making the noise: we can hear a beeping coming
8912
from inside a closed box, so we now know about the beeping, but we
8913
can't tell that it's coming from an alarm clock, so the alarm clock
8914
remains unknown to us.
8915
8916
</div>
8917
8918
<!------------------->
8919
<div class=entry>
8920
8921
By default, Thing now applies the objHeld precondition to a Show
8922
action; this means that SHOW X TO Y requires X to be held if X is an
8923
ordinary Thing.  In addition, NonPortable only requires that the
8924
object be visible.  This change assumes that portable objects need to
8925
be held up for someone else to look at, as though offering the object
8926
to the other person, while non-portable objects can be merely pointed
8927
out but left in place.
8928
8929
</div>
8930
8931
<!------------------->
8932
<div class=entry>
8933
8934
The Vehicle class now treats an OUT command while an actor is inside
8935
the vehicle as meaning to drive or ride the vehicle out of the
8936
vehicle's enclosing location.  In the past, OUT in a vehicle meant
8937
the same thing as in a nested room: GET OUT of the vehicle.  The old
8938
behavior didn't seem to match most players' expectations, and it had
8939
the drawback that it left no standard way of expressing the intention
8940
of driving/riding the vehicle out of its location.
8941
8942
<p>For certain vehicles, it might still be desirable for OUT to mean
8943
GET OUT.  Fortunately, it's easy to override the default behavior on
8944
a case-by-case basis - just override a vehicle's 'out' property to
8945
return nestedRoomOut:
8946
8947
<p><pre>
8948
   car: Vehicle
8949
     out = nestedRoomOut
8950
8951
     // ...other properties...
8952
   ;
8953
</pre>
8954
8955
</div>
8956
8957
<!------------------->
8958
<div class=entry>
8959
8960
In the past, RoomConnector and OneWayRoomConnector didn't apply the
8961
proper preconditions to travel; in particular, they didn't properly
8962
determine the required initial location for the travel, so they didn't
8963
move an actor out of a nested room before attempting the travel.  This
8964
has been corrected; RoomConnector now uses the travel preconditions
8965
formerly defined in RoomAutoConnector, so all RoomConnector subclasses
8966
(including OneWayRoomConnector and RoomAutoConnector) now use the
8967
correct preconditions.
8968
8969
</div>
8970
8971
<!------------------->
8972
<div class=entry>
8973
8974
Enterable and Exitable objects now add a "touchable" pre-condition to
8975
travel through the objects.  In the past, only the pre-conditions for
8976
the underlying connector were applied; since some types of travel
8977
connectors are not themselves physical objects, this occasionally led
8978
to odd results.  In particular, if an Enterable or Exitable was
8979
visible but not touchable (for example, if the object was at a
8980
distance, or separated from the actor by a window), it was possible
8981
to enter it despite its being unreachable.  This type of anomaly should
8982
no longer occur.
8983
8984
</div>
8985
8986
<!------------------->
8987
<div class=entry>
8988
8989
The departure and arrival messages for NPC's now yield more pleasing
8990
results in cases where an NPC arrives or departs from a visible
8991
"remote" location - that is, a location not part of the PC's
8992
outermost room, but connected to the PC's location by a sense
8993
connector (such as a window between two rooms, or a
8994
DistanceConnector).  There are two cases where the departure and
8995
arrival messages are enhanced.
8996
8997
<p>First, when an NPC departs from or arrives at a remote location,
8998
and the other end of the NPC's travel is out of sight, the library
8999
adds the name of the remote location to the arrival or departure
9000
message.  For example: "Bob leaves to the east from the alley," or
9001
"Bob comes down the stairs to the north end of the courtyard."  The
9002
name of the location is taken from the destName property of the NPC's
9003
location.  The location name is only shown when the location is
9004
remote; when an NPC enters or leaves the PC's outermost room, the
9005
traditional messages ("Bob leaves to the east," etc.) are shown.  The
9006
addition of the location name to the message helps clarify that the
9007
NPC is moving around nearby and within sight, but isn't directly at
9008
the PC's location.
9009
9010
<p>Second, when an NPC starts and finishes its journey within sight
9011
of the PC, the library omits the departure message entirely, and
9012
displays a new type of arrival message.  When the entire journey is
9013
within the PC's field of view, we don't wish to describe the
9014
departure and arrival as two separate steps, since the whole journey
9015
can be described as a single operation; this is what the new type of
9016
arrival message does.  The new message is given by the new
9017
TravelConnector method describeLocalArrival(), which the traveler
9018
calls from its describeNpcArrival method when it determines that the
9019
origin is visible to the PC.  TravelConnector.describeLocalArrival()
9020
in turn calls the new Traveler method sayArrivingLocally(), and the
9021
default implementation of this new method simply displays the library
9022
message given by libMessages.sayArrivingLocally().  The library
9023
message displays a message of the form "Bob enters the alley."  Note
9024
that it might sometimes be desirable to customize the travel
9025
connector's describeLocalArrival() method: you could say things like
9026
"Bob climbs the stairs up to the loft," or "Bob squeezes through the
9027
window into the kitchen," for example.
9028
9029
</div>
9030
9031
<!------------------->
9032
<div class=entry>
9033
9034
BasicLocation.cannotGoThatWay now obtains the message to display from
9035
a new property of 'self', cannotGoThatWayMsg.  By default, this
9036
returns &amp;cannotGoThatWayMsg, which is the library message property
9037
for the default message for this case.  You can easily override a
9038
room's message when travel is not possible in a given direction by
9039
overriding cannotGoThatWayMsg to return a single-quoted string with
9040
your custom message.
9041
9042
</div>
9043
9044
<!------------------->
9045
<div class=entry>
9046
9047
The class GuidedInTravelState formerly defined each of the
9048
sayDepartingXxx() methods separately to show the departing-with-guide
9049
library message.  Now, the class instead defines only sayDeparting()
9050
to display this message.  This creates the identical effect by
9051
default, since all of the sayDepartingXxx() methods inherited from
9052
GuidedInTravelState's base class (AccompanyingInTravelState) simply
9053
call sayDeparting().  The advantage of this change is that it allows
9054
GuidedInTravelState's travel message for all of these different
9055
variations to be customized by overriding sayDeparting(), rather than
9056
overriding each sayDepartingXxx() individually.
9057
9058
</div>
9059
9060
<!------------------->
9061
<div class=entry>
9062
9063
SpaceOverlay now checks the "moved" status of its "identity" object,
9064
not its own "moved" status, to determine if it should abandon its
9065
contents on being moved for the first time.  This makes the operation
9066
work properly when the overlay is a component of a ComplexContainer,
9067
which will usually be the case; since only the parent complex
9068
container is actually marked as moved, checking the status of the
9069
child overlay object wasn't enough.  Checking the identity object
9070
ensures that the status of the larger object of which the overlay is
9071
a part is properly taken into account.
9072
9073
</div>
9074
9075
<!------------------->
9076
<div class=entry>
9077
9078
The TravelPushable method beforeMovePushable() now takes a new
9079
third parameter, 'dest', giving the destination of the travel.
9080
9081
</div>
9082
9083
<!------------------->
9084
<div class=entry>
9085
9086
SpaceOverlay now overrides beforeMovePushable() to call
9087
abandonContents().  This ensures that if the object is a
9088
TravelPushable, and it's pushed to an new location, the contents are
9089
abandoned <i>before</i> the actor moves to the destination location.
9090
In the past, the object waited for the normal moveInto() notification
9091
to abandon its contents; but this notification didn't arrive until
9092
after the actor had already moved to the destination location, so the
9093
actor wasn't able to see the contents being abandoned, thus we weren't
9094
able to list the contents properly.
9095
9096
<p>ComplexContainer also overrides beforeMovePushable(), passing the
9097
notification down to any SpaceOverlay components it has.  This
9098
corrects the same problem for a ComplexContainer that's also a
9099
TravelPushable, and which has SpaceOverlay components.
9100
9101
</div>
9102
9103
<!------------------->
9104
<div class=entry>
9105
9106
SpaceOverlay is now more careful about the way it reveals the
9107
contents of the object when it's moved.  In the past, it simply did
9108
an appropriate kind of nested command (LOOK UNDER for an Underside,
9109
for example) to generate the listing.  This generally showed up
9110
before the main report for the action, so when the main report was a
9111
simple default report (such as "Taken"), it created confusion by
9112
suggesting that the default report somehow applied to the last object
9113
listed in the revelation:
9114
9115
<p>
9116
<pre>
9117
   &gt;take box
9118
   Under the box is a rusty can. Taken.
9119
</pre>
9120
9121
<p>There are two changes to the way this listing is generated.
9122
9123
<p>First, the listing is no longer just a generic LOOK UNDER (or
9124
equivalent).  Instead, it uses a new lister, given by the
9125
abandonContentsLister property of the SpaceOverlay object.  Underside
9126
uses undersideAbandonContentsLister by default, and RearSurface and
9127
RearContainer use rearAbandonContentsLister.  These new listers use
9128
more specific language to describe the revelation, of the form
9129
"Moving the box reveals a rusty can underneath" (or "behind").
9130
9131
<p>Second, the SpaceOverlay takes care to move the listing so that it
9132
follows the main report from the command that triggered the listing.
9133
This ensures that the main report remains close to the command line,
9134
which is required if the terse phrasing of the default reports is
9135
to make sense.
9136
9137
<p>There's one exception, though: if the actor performing the command
9138
ends up in a different location at the end of the command, the
9139
listing is <i>not</i> moved to the end of the report.  Instead, the
9140
listing simply stays at the beginning of the command.  This exception
9141
is important because travel usually triggers a description of the new
9142
location, and once we're in the new location, the revelation of the
9143
SpaceOverlay's contents will seem out of place.  It's better in these
9144
cases to leave the contents listing at the start of the reports.
9145
9146
<p>With these two changes, the old listing above is transformed
9147
into this:
9148
9149
<p>
9150
<pre>
9151
   &gt;take box
9152
   Taken. Moving the box reveals a rusty can underneath.
9153
</pre>
9154
9155
</div>
9156
9157
<!------------------->
9158
<div class=entry>
9159
9160
If all of the changes described above to SpaceOverlay's revelation
9161
listing are still not adequate for some special case in your game,
9162
you can now easily suppress the default listing and generate your own
9163
explicit listing instead, thanks to a couple of new features.
9164
9165
<p>First, the new SpaceOverlay property 'neverListOnMove' lets you
9166
suppress the default listing; just set this property to true, and no
9167
listing will ever be generated when the overlay object is moved.  If
9168
the contents are to be abandoned, the abanonment will still happen,
9169
but no automatic mention will be made of it.  Your code is
9170
responsible in these cases for generating any desired listing.
9171
9172
<p>Second, the new method listContentsForMove() generates the
9173
revelation of the contents in the default format.  SpaceOverlay calls
9174
this method itself to generate the automatic message when
9175
appropriate.  If you set neverListOnMove to true in order to suppress
9176
the default revelation listing, you can call listContentsForMove() at
9177
the appropriate juncture in your own code to generate a substitute
9178
listing.  Of course, you could instead completely customize the
9179
listing with your own method; but if you only want to change
9180
<i>where</i> the listing appears, without changing its contents,
9181
listContentsForMove() makes that easy.
9182
9183
<p>Note also that you can customize the standard listing format used
9184
by providing your own lister, and setting the SpaceOverlay object's
9185
abandonContentsLister to refer to your custom lister.
9186
9187
</div>
9188
9189
<!------------------->
9190
<div class=entry>
9191
9192
In the default Floor class, there were a couple of problems with the
9193
commands SIT ON FLOOR, STAND ON FLOOR, and LIE ON FLOOR that have now
9194
been corrected.  First, when standing in a nested room, STAND ON
9195
FLOOR incorrectly failed with the message "You're already standing."
9196
Second, when already sitting, lying, or standing on the floor,
9197
another command to do the same thing was incorrectly accepted; it's
9198
now rejected with an appropriate message (such as "You're already
9199
sitting on the floor").
9200
9201
</div>
9202
9203
<!------------------->
9204
<div class=entry>
9205
9206
If the player character was in a nested room, and typed a command to
9207
leave the nested room, and immediately followed with an AGAIN
9208
command, the AGAIN incorrectly succeeded, making it look like the
9209
character was getting out of the nested room repeatedly without
9210
getting back in.  This has been corrected; an appropriate message
9211
("you're not in the booth") is now displayed on the errant repetition.
9212
9213
</div>
9214
9215
<!------------------->
9216
<div class=entry>
9217
9218
In ActorTopicDatabase.initiateTopic(), the conversation is "noted"
9219
only if an InitiateTopic is found to handle the request.  Noting the
9220
conversation means that we set the actor's last interlocutor to the
9221
player character, so this change means that initiateTopic() won't
9222
affect the actor's interlocutor unless a conversation is actually
9223
initiated.  (In the past, the routine always noted the conversation.
9224
This caused odd side effects when initiateTopic() was called
9225
speculatively, without knowing for sure that an InitiateTopic was
9226
actually available, since the interlocutor changed even though no
9227
conversational action was visible to the player.  This change ensures
9228
that the interlocutor will only change when a conversation actually
9229
takes place.)
9230
9231
</div>
9232
9233
<!------------------->
9234
<div class=entry>
9235
9236
When an InConversationState object becomes the active state for an
9237
actor, it remembers the previously active state so that it can, by
9238
default, transition back to that previous state when the conversation
9239
ends.  In the past, the InConversationState class remembered
9240
<i>any</i> previous state and used it as the new state at the end of
9241
the conversation.  This has been changed.  Now, the class remembers
9242
the previous state only if the previous state is a
9243
ConversationReadyState, or there's no other previous state already
9244
remembered.  This change makes it easier for an actor to interrupt a
9245
conversation with another activity, and later resume the
9246
conversation, because the interrupting state will no longer "take
9247
over" at the end of the conversation.  You can still explicitly set
9248
the end-of-conversation state explicitly to anything you want; this
9249
change only affects the default state transitions that occur in the
9250
absence of any explicit settings.
9251
9252
</div>
9253
9254
<!------------------->
9255
<div class=entry>
9256
9257
The HELLO and TALK TO commands now defer the implied topic inventory
9258
until the end of the turn, if the response to the HELLO or TALK TO
9259
contains any non-default reports.  This is important because a
9260
non-default report could set the ConvNode for the responding actor,
9261
but such a change doesn't take effect until the transcript is fully
9262
processed at the end of the turn.  In the past, HELLO and TALK TO
9263
always showed the topic inventory right away, so the inventory didn't
9264
necessarily match the new ConvNode's active topics.  With this
9265
change, a ConvNode change within a HELLO or TALK TO will be properly
9266
reflected in the topic inventory.
9267
9268
</div>
9269
9270
<!------------------->
9271
<div class=entry>
9272
9273
The new ConvNode property 'isSticky' lets you create a "sticky"
9274
conversation node.  By default, nodes are non-stick: this yields the
9275
traditional behavior, where the NPC leaves the node if a response
9276
doesn't explicitly stay there.  (If the node is active, and the NPC
9277
shows a response that doesn't set any new node, the actor's current
9278
node is set to nil.)
9279
9280
<p>If you set 'isSticky' to true for a node, the node will stay
9281
active if the NPC shows a response that doesn't set a new node.  In
9282
other words, the "default next node" for any response while the
9283
sticky node is active is the sticky node itself, rather than nil.
9284
9285
<p>Sticky nodes are useful in cases where you want an actor to drive
9286
a conversation along a particular thread, but you still want to allow
9287
the player to digress by talking about other topics.  As long as a
9288
digression doesn't explicitly set a new node, the sticky node will
9289
remain active.
9290
9291
</div>
9292
9293
<!------------------->
9294
<div class=entry>
9295
9296
DefaultCommandTopic now has a matchScore of 3, which makes the
9297
library choose it over a DefaultAnyTopic if both kinds of default
9298
topics are active for a given response.  (In the past,
9299
DefaultCommandTopic had the same matchScore as a DefaultAnyTopic, so
9300
in cases where both kinds were active the library chose one
9301
arbitrarily.  The DefaultCommandTopic should always take precedence,
9302
as it now does, because it's the more specific kind of response.)
9303
9304
</div>
9305
9306
<!------------------->
9307
<div class=entry>
9308
9309
AltTopic now takes its setting for the 'impliesGreeting' property
9310
from its enclosing topic.  This ensures that an AltTopic used within
9311
a HelloTopic or the like will behave the same as its enclosing main
9312
topic by default.
9313
9314
</div>
9315
9316
<!------------------->
9317
<div class=entry>
9318
9319
ByeTopic and ImpByeTopic now work together the same way that
9320
HelloTopic and ImpHelloTopic work together.  Specifically, ByeTopic is
9321
now a catch-all that matches both explicit GOODBYE commands and
9322
implied conversation endings.  (Implied goodbyes happen when the
9323
player character just walks away from a conversation, or the NPC gets
9324
"bored" from lack of attention).  ImpByeTopic still matches only
9325
implied goodbyes; since it's the more specific of the two, it now uses
9326
an elevated matchScore.  This means that if both a ByeTopic and an
9327
ImpByeTopic are active at the same time, the ImpByeTopic will be
9328
chosen for an implied goodbye, and the ByeTopic will be chosen for an
9329
explicit GOODBYE command.
9330
9331
<p>This change makes it easier to program catch-all goodbye messages,
9332
while still allowing differentiation when desired.  To create a
9333
catch-all message that handles both explicit and implicit goodbyes,
9334
just create a ByeTopic.  If you want to differentiate, create one of
9335
each: the ByeTopic will be chosen for the explicit GOODBYE commands,
9336
since the ImpByeTopic won't match those; and the ImpByeTopic will be
9337
chosen for implied goodbye, because both will match, but the
9338
ImpByeTopic's higher matchScore will ensure that it's selected over
9339
the ByeTopic.
9340
9341
<p>Along the same lines, HelloGoodbyeTopicObj now matches implied
9342
as well as explicit goodbyes.  (In the past, it handled implied and
9343
explicit greetings, but only explicit goodbyes.)
9344
9345
</div>
9346
9347
<!------------------->
9348
<div class=entry>
9349
9350
Some of the behavior of InConversationState.endConversation has been
9351
moved to the base ActorState class.  This ensures that the active
9352
ConvNode will be notified if the player walks away from a
9353
conversation.
9354
9355
</div>
9356
9357
<!------------------->
9358
<div class=entry>
9359
9360
The library messages for scoring (showScoreMessage,
9361
showScoreNoMaxMessage, showScoreRankMessage, showFullScorePrefix) now
9362
refer explicitly to "you", not to the player character.  Since the
9363
score is a meta-game feature, it should be attributed directly to the
9364
player, not to the player character.  This is especially important in
9365
games that refer to the player character in the first or third
9366
person, since the distinction between player and player character is
9367
more evident in these cases than it is in second-person games.
9368
9369
</div>
9370
9371
<!------------------->
9372
<div class=entry>
9373
9374
The library message for trying to put an object inside an another
9375
object that already contains the first object (i.e., the "circular
9376
containment" message) now reports the objects as specified, rather
9377
than possibly showing an intermediate container.  In the past, an
9378
intermediate container was shown in some circumstances, especially
9379
when a ComplexContainer was involved; this produced the wrong
9380
messages in some cases.
9381
9382
</div>
9383
9384
<!------------------->
9385
<div class=entry>
9386
9387
In the past, the multiple object announcement ("red book: Taken") was
9388
missing in in some cases where the action was remapped (via remapTo).
9389
This has been corrected.
9390
9391
</div>
9392
9393
<!------------------->
9394
<div class=entry>
9395
9396
The implied action message generator now allows for "silent" implied
9397
actions - implied actions that behave as usual but generate no
9398
announcement text (the normal announcement is the message of the form
9399
"(first opening the door)" shown at the start of the response to the
9400
command).
9401
9402
<p>First, the new libMessages method silentImplicitAction() can be
9403
used in place of the standard announceImplicitAction() to generate
9404
the announcement.  silentImplicitAction() simply shows no message.
9405
To use it, perform the implied action with a call like this:
9406
9407
<p><pre>
9408
   tryImplicitActionMsg(&amp;silentImplicitAction, Open, self);
9409
</pre>
9410
9411
<p>Second, the lister that aggregates a set of implicit actions into a
9412
single announcement message now accepts the empty messages generated
9413
by silentImplicitAction().  This ensures that silent implied actions
9414
can be mixed with announced implied actions in a single command, and
9415
a sensible aggregate announcement will be displayed.
9416
9417
</div>
9418
9419
<!------------------->
9420
<div class=entry>
9421
9422
Thing.setContentsSeenBy() incorrectly marked the object's contents as
9423
having been seen by 'gActor' rather than by the actor passed as a
9424
parameter to the method.  This has been corrected.
9425
9426
</div>
9427
9428
<!------------------->
9429
<div class=entry>
9430
9431
In PresentLater, when the object is made present (via the makePresent
9432
method, or any of the related methods), the object and its contents
9433
are specifically marked as seen by the player character, to the
9434
extent the player character can actually see them at the moment they
9435
become present in the location.  In most cases, when an object comes
9436
into play dynamically via the PresentLater mechanism, the sudden
9437
appearance is the result of some specific event that the game will
9438
describe through custom handling - that is, the game will
9439
specifically mention the new object to the player, so the player
9440
character should remember having seen the object.
9441
9442
</div>
9443
9444
<!------------------->
9445
<div class=entry>
9446
9447
In a two-object command (such as PUT VASE ON TABLE), the parser now
9448
retains the meaning of a pronoun used in the command, regardless of
9449
which object slot the pronoun is used in.  For example, after the
9450
command PUT VASE ON IT, the pronoun "it" is set to refer to the
9451
indirect object, even though "it" would normally refer to the direct
9452
object after a PUT X ON Y command.
9453
9454
<p>In the past, the parser unconditionally set the pronoun antecedent
9455
after a two-object command to the second-resolved object, which in
9456
many such verbs is the direct object.  So, after PUT VASE ON IT, the
9457
pronoun "it" previously referred to the vase.  Due to this change,
9458
though, the explicit use of the word "it" directly within the command
9459
causes meaning of "it" to be left unchanged by the command.  This
9460
change doesn't affect the behavior when no pronoun is used in the
9461
command, so PUT VASE ON TABLE still causes "it" to refer to the vase
9462
on the subsequent command.
9463
9464
</div>
9465
9466
<!------------------->
9467
<div class=entry>
9468
9469
ConsultTopic and DefaultConsultTopic now refrain from setting any
9470
pronoun antecedents for the topic.  This means that after any
9471
consultation command (LOOK UP, FIND IN, etc.), the pronoun antecedent
9472
will be the consultable object, not the topic last sought.
9473
9474
</div>
9475
9476
<!------------------->
9477
<div class=entry>
9478
9479
TopicTAction (used for commands such as ASK ABOUT and CONSULT ABOUT)
9480
didn't work properly if a reflexive pronoun was used as the direct
9481
object, referring back to the topic phrase: LOOK UP BOOK IN ITSELF,
9482
for example.  This showed a couple of symptoms, including "Nothing
9483
obvious happens" responses and run-time errors.  The problem has been
9484
corrected; the action now looks to the topic phrase to resolve the
9485
direct object, producing consistent and appropriate results.
9486
9487
</div>
9488
9489
<!------------------->
9490
<div class=entry>
9491
9492
When a command is directed to an NPC (as in BOB, OPEN DOOR), and the
9493
parser has to prompt interactively for disambiguation or for a
9494
missing noun phrase, the parser now treats gender-matched
9495
third-person pronouns in the reponse as referring to the target
9496
actor.  For example:
9497
9498
<p><pre>
9499
   &gt;look at bob
9500
   He's wearing a red sweater.
9501
9502
   &gt;bill, examine
9503
   What do you want Bill to look at?
9504
9505
   &gt;his book
9506
   The book looks old and dusty; the title on the cover is faded
9507
   to the point of being unreadable.
9508
</pre>
9509
9510
<p>In the past, the parser would have taken the "his" in the
9511
interactive response to refer to Bob, since Bob would have been the
9512
pronoun antecedent up until that point (by virtue of having been
9513
mentioned in the previous command).  With this change, the parser
9514
takes "his" to refer to Bill.  This fits with the phrasing of the
9515
prompt text, and also with the fact that Bill was mentioned more
9516
recently in a command (specifically, in the incomplete "examine"
9517
command).
9518
9519
<p>Similarly, reflexive third-person pronouns (HIMSELF, HERSELF,
9520
ITSELF, THEMSELVES) in interactive responses are taken as referring
9521
to the target actor, when the gender matches.
9522
9523
</div>
9524
9525
<!------------------->
9526
<div class=entry>
9527
9528
The parser is now more consistent in its treatment of truncated
9529
vocabulary matches.  (Truncated matches are words in the player's
9530
command that match longer object names defined in the game, by
9531
truncating the longer object names to the dictionary's minimum length.
9532
For example, the default English dictionary truncation length is 6
9533
characters, meaning that the player can shorten the word FLASHLIGHT to
9534
FLASHL, FLASHLI, etc., when entering commands.)
9535
9536
<p>In the past, the parser treated exact matches as stronger than
9537
truncated matches for singular definite noun phrases (the most common
9538
kind of noun phrase: TAKE BOOK, OPEN THE BOX).  Any time the parser
9539
matched some names exactly and other names only after truncation for
9540
the same user input, the parser kept only the exact matches, filtering
9541
out the truncated matches.  This rule hasn't been changed; what's
9542
changed is that it has now been extended to every kind of noun phrase,
9543
including indefinite phrases (TAKE A BOOK) and plural phrases (TAKE
9544
BOOKS).
9545
9546
</div>
9547
9548
<!------------------->
9549
<div class=entry>
9550
9551
<a name='pluralToNounExpansion'></a>
9552
In the English parser, when the parser matches a plural phrase (i.e.,
9553
a phrase with a vocabulary word defined under the 'plural' property),
9554
the parser now includes both 'plural' <i>and</i> 'noun' matches for
9555
the word.  In the past, only the 'plural' matches were included.
9556
9557
<p>In some cases, it's convenient to define a word that's
9558
grammatically a plural under the 'noun' property, because a single
9559
game object encompasses what looks to the user like a set of
9560
something: a bookcase might define "shelves" as a noun, for example,
9561
since the individual shelves aren't modeled as separate objects.  This
9562
change ensures that if other objects are in scope that define the same
9563
word under the 'plural' property, the bookcase will still match the
9564
word "shelves" when the noun phrase is resolved.
9565
9566
<p>This change doesn't actually make much difference most of the time,
9567
but it is frequently significant in "topic" phrases (as in ASK ABOUT).
9568
Topic phrases have very wide scope, so a particular word can match
9569
numerous objects from all over the game.  In these cases, the old
9570
scheme that included only 'plural' matches was overly exclusive,
9571
causing the parser to omit objects from the topic resolution that the
9572
author would at first glance have expected to be included.  The new
9573
more inclusive matching should reduce the potential for confusing
9574
match exclusions in these cases.
9575
9576
</div>
9577
9578
<!------------------->
9579
<div class=entry>
9580
9581
<a name='#nounEndingToAdjEndingExpansion'></a>
9582
The English parser is now more inclusive in matching nouns and
9583
adjectives at the ends of "topic" phrases.  (Topic phrases are used in
9584
commands like ASK ABOUT and TELL ABOUT, where the player can refer to
9585
physical objects as well as to abstract Topic objects, and can even
9586
use random text that doesn't correspond to any game objects.)
9587
9588
<p>Normally, when the last word of a noun phrase can match one or more
9589
objects in scope that define the word under the 'noun' property, the
9590
parser will ignore any additional in-scope objects that match the same
9591
word under the 'adjective' property.  For example, if there's a desk
9592
in scope that defines 'desk' as a noun, and there's also a desk drawer
9593
that defines 'desk' as an adjective, the parser will interpreter LOOK
9594
AT DESK as referring to the desk, not to the drawer.  However, if
9595
there's a red book present, but there's no object in scope that
9596
defines 'red' as a noun, the parser takes READ RED as referring to the
9597
red book, even though BOOK was left unstated.  This combination of
9598
rules gives the player the convenience of abbreviating the name of an
9599
object to a unique adjective, while avoiding spurious ambiguity in
9600
cases like the desk-and-drawer exmaple.
9601
9602
<p>In cases of "global" scope, though, this strategy isn't as
9603
beneficial.  When resolving a topic phrase, objects from all over the
9604
game have to be considered "in scope" even though they're not
9605
physically present, as it's perfectly reasonable for the player to ASK
9606
ABOUT something that was seen earlier in the game but isn't physically
9607
present at the time of the question.  As a result, the elimination of
9608
adjective bindings for a word can cause subtle problems that are very
9609
difficult to track down, and which sometimes can't be easily fixed
9610
without creating other problems.  Two objects could happen to share
9611
the same vocabulary words, in one case as an adjective and in the
9612
other case as a noun, even though the objects are completely
9613
unrelated.  Thus, the existence of one object can change the way
9614
another object's vocabulary words are treated when matching a topic
9615
phrase.
9616
9617
<p>The English parser now treats topic resolution differently.  When
9618
resolving a topic phrase, the parser no longer makes the strict
9619
noun/adjective distinction.  Instead, the parser considers both kinds
9620
of vocabulary to match.  So, if the player types ASK BOB ABOUT DESK in
9621
our example with the drawer, both the desk and the drawer are now
9622
considered possible topic matches.
9623
9624
<p>This change has the potential to create a different sort of
9625
problem, in that it could include <i>too many</i> possible matches for
9626
a topic phrase.  However, this is a much easier problem to deal with
9627
than the old one, and in most cases won't even be noticeable as a
9628
problem.  In the first place, topic phrases don't require
9629
disambiguation in the normal sense; the parser never asks the player
9630
which object was intended, so the more inclusive matching won't
9631
degrade the user interface by generating more disambiguation queries.
9632
Second, it's much easier to understand why an extra object is matching
9633
a given vocabulary word than to understand why a given object is
9634
failing to match.  A failure to match indicates that some other object
9635
is defining the same word under another part of speech, but it doesn't
9636
tell you which object or where it's defined; when too many objects
9637
match, in contrast, you can easily see (using the debugger, for
9638
example) which extra objects are matching, and make any desired
9639
vocabulary adjustments.  Third, in the vast majority of cases, the
9640
extra matches are completely harmless and not even noticeable.  Topics
9641
are generally handled in conversations, and conversations have to
9642
explicitly include responses for all of the topics they want to match.
9643
If an extra object or two show up in vocabulary matching for a given
9644
conversational command, it won't usually matter, because those
9645
unexpected objects won't have topic matches in the conversation anyway
9646
and will thus simply be ignored.  In cases where you want a
9647
conversation to distinguish among objects with similar vocabulary, you
9648
can add the necessary distinguishing vocabulary to the objects just as
9649
you would in cases of ordinary ambiguity, and you can tweak the topic
9650
list (using match scores, for example) to control which response is
9651
used for which vocabulary.  In the rare cases where it's not
9652
straightforward to fine-tune the matching using object vocabulary, you
9653
can always resort to using regular expressions as the topic match
9654
criteria.
9655
9656
</div>
9657
9658
<!------------------->
9659
<div class=entry>
9660
<a name='global_scope_noun_adj'></a>
9661
9662
Consider a situation where a given object is entered in the dictionary
9663
with two words for a given part of speech, and one of the words
9664
happens to be a leading substring of the other word, and both words
9665
are long enough to trigger "truncated" matching (that is, each word is
9666
at least six characters long, in the default dictionary truncation
9667
configuration).  For example, suppose a given object is entered in the
9668
dictionary with 'noun' words for WINDOW and WINDOWSILL.  Now, if the
9669
player enters a command using the shorter word (WINDOW), the raw
9670
dictionary match list will contain two matches for this object: one
9671
for the exact match to the shorter word, and one for the truncated
9672
match to the longer word.
9673
9674
<p>In the past, this situation sometimes had undesirable results.  In
9675
most cases, the two matches to the same object were collapsed into a
9676
single match, but the "match flags" from the two matches were combined
9677
- so both matches were marked as truncated.  Depending on what other
9678
objects were in scope at the time, this had the effect of eliminating
9679
the object from consideration as a resolution of the noun phrase: even
9680
though it had an exact match in the dictionary, the resolver saw it as
9681
a truncated match because of the combination of the two sets of match
9682
flags.  This was especially likely to affect topic phrases (ASK ABOUT,
9683
for example), because the global scope made it much more likely that
9684
other objects would have exact matches for the same vocabulary.
9685
9686
<p>The parser is now smarter about the way it combines these sorts of
9687
redundant matches.  Instead of simply OR'ing together the match flags,
9688
the parser now specifically keeps only the "strongest" match in these
9689
cases.  In our example, the parser sees that there's a truncated
9690
dictionary match (WINDOWSILL) and an exact match (WINDOW) for the same
9691
object, so it now decides to consider the match to be exact.
9692
9693
</div>
9694
9695
<!------------------->
9696
<div class=entry>
9697
9698
The English parser now accepts IN <i>object</i>, INTO <i>object</i>,
9699
and IN TO <i>object</i> as verb synonyms for ENTER <i>object</i>.
9700
These aren't exactly valid English grammar, but they have a certain
9701
linguistic consistency with other telegraphic IF-ese constructs, and
9702
they seem to naturally occur to some players.  These variations all
9703
have an obvious meaning to an English speaker, and they're not
9704
ambiguous with any other commands, so there should be no harm in
9705
adding them as convenient abbreviations.
9706
9707
</div>
9708
9709
<!------------------->
9710
<div class=entry>
9711
9712
After a misspelling, if the player typed OOPS but left off the
9713
corrected spelling (i.e., just typed OOPS by itself on the command
9714
line), the parser responded with a message saying that OOPS isn't
9715
allowed right now.  This has been corrected; the parser now responds
9716
with a new message explaining the correct syntax, and gives the user
9717
another chance to enter the OOPS command.
9718
9719
</div>
9720
9721
<!------------------->
9722
<div class=entry>
9723
9724
When a single player command triggers more than one implied action
9725
(for example, GO NORTH might trigger OPEN DOOR, which in turn might
9726
trigger UNLOCK DOOR), the reporting mechanism had a couple of problems
9727
when the doubly-nested action (UNLOCK DOOR in our example) itself
9728
triggered a nested action, such as by remapTo or nestedAction.  First,
9729
the reported order of the implied actions was reversed ("first opening
9730
the door, then unlocking it"); second, the doubly-nested one reported
9731
the nested action rather than the original implied action.  Both of
9732
these have now been corrected.
9733
9734
</div>
9735
9736
<!------------------->
9737
<div class=entry>
9738
9739
When you synthesize an action programmatically (via a function such
9740
as replaceAction or nestedAction), the library has to choose a
9741
language-specific final subclass of the generic action you specify.
9742
It does this by choosing a VerbRule that's subclassed from the base
9743
action.  In the past, the choice was entirely arbitrary.  Now, the
9744
library is a little pickier: it now chooses only a final subclass,
9745
never an intermediate class.  That is, it always chooses a VerbRule
9746
which hasn't been further subclassed (or modified with 'modify').
9747
The old, less selective algorithm occasionally caused oddities, such
9748
as choosing a base VerbRule that was subclassed with 'modify', thus
9749
picking up pre-'modify' values of properties such as the verb's
9750
descriptive text.
9751
9752
</div>
9753
9754
<!------------------->
9755
<div class=entry>
9756
9757
The conversationManager object now provides a simple extensibility
9758
mechanism that lets you add your own custom conversation tags.  To
9759
add custom tags, use 'modify' to extend the conversationManager
9760
object, then add two things.  First, define the customTags property,
9761
giving a string with the new tag names you want to add.  The tag
9762
names must be in lower-case letters; do not include the angle
9763
brackets or the leading period in the tag name.  Separate multiple
9764
tag names with "|" symbols.  Second, define a doCustomTag(tag,arg)
9765
method that processes your custom tag or tags.  The 'tag' argument is
9766
a string giving the custom tag that was matched in the output stream;
9767
only the tag name will be included, not including the angle brackets
9768
or leading period.  The 'arg' method is a string giving the argument
9769
to the tag, if any; this is simply the part inside the angle brackets
9770
following any whitespace after the tag.
9771
9772
</div>
9773
9774
<!------------------->
9775
<div class=entry>
9776
9777
SensoryEmanation and its subclasses Noise and Odor will now let you
9778
use Script objects for the hereWithSource and hereWithoutSource
9779
properties.  This is handy in cases where you want to vary the
9780
object's description over time.  If you define these properties as
9781
Script objects, the SensoryEmanation object will invoke their
9782
doScript() methods when an emanation message is to be displayed.
9783
9784
</div>
9785
9786
<!------------------->
9787
<div class=entry>
9788
9789
The Keyring class has a new method, getLooseKeys(actor), that
9790
identifies the loose keys in an actor's possession that are eligible
9791
for automatic attachment when the keyring is taken.  By default, this
9792
returns the actor's direct contents (i.e., the objects the actor is
9793
directly holding).
9794
9795
<p>This can be overridden to consider, for example, loose keys held in
9796
the actor's pocket.  To prevent the keyring from automatically
9797
grabbing any keys when it's taken, simply override this method to
9798
return an empty list.  Note that you don't need to bother limiting the
9799
returned list to include only valid keys, since the caller does this
9800
by considering only objects for which isMyKey() returns true.
9801
9802
</div>
9803
9804
<!------------------->
9805
<div class=entry>
9806
9807
The function withParserGlobals() now takes an additional parameter
9808
giving the actor who issued the command.  (This is an internal
9809
function that's probably not used at all by existing game code, so it
9810
should have no impact on games.  If you are calling this function,
9811
though, note that you'll need to supply the extra parameter.)
9812
9813
</div>
9814
9815
<!------------------->
9816
<div class=entry>
9817
9818
The menu system now sets the main content banner window to use
9819
scrollbars if possible, and automatically scroll to show new text
9820
in any case.  This ensures that hint lists that are too long to fit
9821
in the window will scroll as needed to keep the last hint in view.
9822
9823
</div>
9824
9825
<!------------------------------- 3.0.6o --------------------------------->
9826
<div class="sepbar"><a name='306o'></a>3.0.6o</div>
9827
<p><b><i>Released 3/14/2004</i></b>
9828
<p>
9829
9830
<div class=firstentry>
9831
9832
<p><b>Possible compatibility-breaking change:</b> The property
9833
formerly named 'vocabWords_' has been renamed to 'vocabWords' (the
9834
change is that the underscore formerly at the end of the name has been
9835
removed).  The underscore suffix is conventionally used in the library
9836
to indicate an internal library property that isn't normally for use
9837
by game code, which obviously isn't appropriate in this case, as this
9838
is the property that games usually initialize to set an object's
9839
vocabulary words.
9840
9841
<p>You should search for instances of 'vocabWords_' in your existing
9842
code, and replace them with 'vocabWords'.  Most existing game code
9843
will probably have few, if any, instances of this property name, since
9844
most object definitions in existing game code probably use the
9845
standard library templates to set this property's value without giving
9846
its name.  Even so, you should search through your code and update any
9847
mentions to use the new name.
9848
9849
</div>
9850
9851
<!------------------->
9852
<div class=entry>
9853
9854
The method getOutermostRoom(), which was previously defined in
9855
BasicLocation and NestedRoom, has been moved instead to Thing.  This
9856
ensures that the method will work properly even when a nested room is
9857
located within a non-room object.  The Thing definition simply returns
9858
the enclosing location if there is one, or 'self' if not.
9859
9860
</div>
9861
9862
<!------------------->
9863
<div class=entry>
9864
9865
The new TopicEntry subclass AskTellGiveShowTopic makes it easy to
9866
define a response that covers ASK, TELL, GIVE, and SHOW for a given
9867
object or set of objects.  It's sometimes convenient to be able to
9868
treat all of these commands as equivalent in handling a response.
9869
9870
<p>AskTellGiveShowTopic is based on the new class
9871
TopicOrThingMatchTopic, which can be subclassed to create other
9872
combinations of other subsets of these four verbs (or to add topic
9873
entries for new custom game-defined verbs).  This new class combines
9874
the features of the "Thing" and "Topic" base classes for topic
9875
entries.
9876
9877
</div>
9878
9879
<!------------------->
9880
<div class=entry>
9881
9882
ConvNode has a new method, autoShowTopics(), that returns true if the
9883
node is to show a topic inventory automatically on activation.  By
9884
default, this method returns true if the node contains any active
9885
SpecialTopic entries.  You can override this if desired to generate a
9886
topic inventory automatically under other conditions, or to suppress
9887
the automatic inventory when an active special topic is present
9888
(although the latter probably isn't a good idea).
9889
9890
<p>The main reason you might want to generate a topic inventory
9891
automatically on activating a node is that the node contains one or
9892
more obscure topics that players will be unlikely to guess on their
9893
own.  If it's unlikely that the player would think to ask just the
9894
right thing at just the right time, a topic inventory can help guide
9895
them through the conversation by showing the possibilities.  As
9896
always, only the topics you specifically mark as suggested (with
9897
SuggestedAskTopic, etc) will be listed in the inventory.  When possible,
9898
it's probably better from a game-design perspective to lead players
9899
into asking the right questions more subtly, by putting the right
9900
cues in the conversation itself; when this is impractical, the topic
9901
inventory is a usable substitute.
9902
9903
</div>
9904
9905
<!------------------->
9906
<div class=entry>
9907
9908
The pronoun expansion for CollectiveGroup objects that was introduced
9909
in 3.0.6n has been partially removed.  In the past, when an individual
9910
object was associated with a CollectiveGroup object, the parser
9911
automatically added the group object into consideration for resolving
9912
a subsequent pronoun referring to the individual.  This was meant to
9913
provide better fidelity for resolving pronouns in these cases, but it
9914
led to new problems when the original noun phrase could only have
9915
referred to the individual.  To correct the problems, the parser no
9916
longer puts the collective group into consideration when a pronoun
9917
refers to one of the group's individuals.
9918
9919
<p>The other direction still applies, though: when a pronoun refers to
9920
a CollectiveGroup object, the parser puts the group's associated
9921
individuals into consideration for resolving the pronoun.
9922
9923
</div>
9924
9925
<!------------------->
9926
<div class=entry>
9927
9928
A bug in the CommandTopic class (introduced in 3.0.6n) prevented it
9929
from matching a single Action class as the matchObj correctly.  (It
9930
did work properly when a list of Action classes was given, but not
9931
when a single object was given.)  This has been corrected.
9932
9933
</div>
9934
9935
<!------------------->
9936
<div class=entry>
9937
9938
The HelloGoodbyeTopic class now has its impliesGreeting property set
9939
to true, ensuring that this topic type won't trigger an implied
9940
greeting.  Since a HelloGoodbyeTopic is itself a greeting, an implied
9941
greeting would be undesirable, not to mention that it caused a
9942
run-time error when it occurred.
9943
9944
</div>
9945
9946
<!------------------->
9947
<div class=entry>
9948
9949
A bug in ComplexContainer caused a problem when an object was
9950
initially located in one of the the complex container's sub-containers
9951
via the 'subLocation' property.  In the past, the ComplexContainer
9952
didn't properly re-initialize the object's 'location' property to
9953
reflect that it was actually in the sub-container.  This has been
9954
fixed.
9955
9956
<p>The problem manifested as strange behavior when the contained
9957
object was removed from the sub-container (via TAKE or the like).  In
9958
particular, because the object's 'location' was still set to the
9959
ComplexContainer, the object wasn't properly removed from the
9960
sub-container's contents list, so the object appeared to still be in
9961
the sub-container as well as in its new location.
9962
9963
</div>
9964
9965
<!------------------->
9966
<div class=entry>
9967
9968
A couple of problems involving formatting and real-time events have
9969
been fixed.  In 3.0.6i, fuses and daemons - including the real-time
9970
versions - started running with a transcript context, which means
9971
that their text output is captured.  This caused some interactions
9972
with the input manager that weren't taken into account properly in
9973
the library.
9974
9975
<p>First, if a real-time event itself stopped and asked for input from
9976
the user (by reading a new command line, for example), the transcript
9977
capturing prevented the text displayed by the event from showing up at
9978
all until after the user entered something on the new command line.
9979
It was possible to work around this by deactivating the transcript
9980
prior to showing any output in the real-time event, but this is no
9981
longer necessary.
9982
9983
<p>Second, even if a real-time event didn't display anything, its mere
9984
silent firing caused an extra blank line to show up immediately after
9985
the user next pressed the Enter key to finish a command line.
9986
9987
<p>Both of these problems are now corrected, so there's no need for
9988
real-time events to do anything special with respect to output
9989
formatting or command-line input.
9990
9991
</div>
9992
9993
<!------------------->
9994
<div class=entry>
9995
9996
The new pre-defined message object parameter 'pc' can be used to
9997
refer directly to the player character.  This is similar to the 'actor'
9998
parameter, but refers to the player character actor even if an NPC is
9999
the current active character.  An expression such as "{you pc/he}"
10000
thus refers to the current gPlayerChar, not to the current gActor.
10001
10002
</div>
10003
10004
<!------------------->
10005
<div class=entry>
10006
10007
The library messages for scoring (showScoreMessage,
10008
showScoreNoMaxMessage, showScoreRankMessage, showFullScorePrefix)
10009
incorrectly referred to the current actor rather than the current
10010
player character, which resulted in attributing the score to an NPC
10011
rather than to the player if a score message was generated on another
10012
actor's turn.  These messages now explicitly refer to the player
10013
character.
10014
10015
</div>
10016
10017
<!------------------------------- 3.0.6n --------------------------------->
10018
<div class="sepbar"><a name='306n'></a>3.0.6n</div>
10019
<p><b><i>Released 3/6/2004</i></b>
10020
<p>
10021
10022
<div class=firstentry>
10023
10024
<b>Major compatibility-breaking change:</b> The library's main
10025
entrypoints to the game have changed.  Existing games <b>must</b>
10026
be modified to accommodate this change.
10027
10028
<p>In the past, the game code was responsible for defining two
10029
entrypoints: main() and mainRestore().  The template games generated
10030
by Workbench's "New Project" command defined these two functions as
10031
one-liners that called mainCommon(), where the real action took place.
10032
10033
<p>In the new arrangement, the library now invokes methods of a
10034
new object, gameMain, which each game <b>must</b> define.  For your
10035
convenience, the library defines a class, GameMainDef, that you
10036
can use as the base class of your gameMain object.  This base class
10037
defines suitable defaults for the required methods, so you only have
10038
to override what you need to customize.  Overall, this change should
10039
result in much less required startup code for each game.
10040
10041
<p>If you use GameMainDef as the base class of your gameMain object,
10042
you're only required to define one property in it:
10043
10044
<ul>
10045
10046
<li>initialPlayerChar - set this property to the Actor object that
10047
serves as the initial player character in the game.  You <b>must</b>
10048
set this; GameMainDef can't provide a default for you here.
10049
10050
</ul>
10051
10052
<p>In addition, there are a couple of optional optional methods that
10053
you can use for customization:
10054
10055
<ul>
10056
10057
<li>showIntro() - show the game's introduction.  Most games will want
10058
to override this to show the prologue text for the game.
10059
10060
<li>showGoodbye() - show the game's "goodbye" message.  Override this
10061
if you want to add a parting message as the game terminates.
10062
10063
</ul>
10064
10065
<p>Most games will find it sufficient to define only initialPlayerChar
10066
and showIntro(), and simply inherit the default handling for everything
10067
else from GameMainDef.  However, there are several additional methods
10068
that you can override if you want to do something special.
10069
10070
<ul>
10071
10072
<li>newGame() - the library invokes this method to start a new game.
10073
The default version calls showIntro() to show the introductory text,
10074
then runs the main command loop until the player quits, then calls
10075
showGoodbye() to show the goodbye message.  You can override this
10076
if you want to do something extra, such as showing a pre-game
10077
options screen.
10078
10079
<li>restoreAndRunGame(filename) - the library invokes this method to
10080
restore and start running a saved game that the user selected when
10081
launching the interpreter.  It should rarely be necessary to override
10082
this.
10083
10084
<li>setGameTitle() - the library invokes this method at start-up to
10085
set the interpreter's window title to show the game's title, as
10086
defined in versionInfo.name.  It should rarely be necessary to
10087
override this.
10088
10089
</ul>
10090
10091
<p>If your existing game code uses the Workbench-generated template,
10092
or you follow the same pattern, then rewriting your code to fit the
10093
new design is relatively straightforward.  Just follow these steps.
10094
10095
<ul>
10096
10097
<li><b>Save a copy</b> of your existing code before you do anything
10098
else.  If things don't seem to work properly after you finish
10099
applying this update, you can compare the modified version with your
10100
backup copy to help track down the problem.
10101
10102
<li><b>Delete</b> your main() and mainRestore() functions.  Your game
10103
code doesn't need to define these routines at all any more, since the
10104
library now defines them.
10105
10106
<li><b>Create</b> a new object definition for gameMain:
10107
10108
<p><pre>   gameMain: GameMainDef
10109
     initialPlayerChar = me
10110
     showIntro()
10111
     {
10112
       // TO DO!
10113
     }
10114
   ;
10115
</pre>
10116
10117
<li><b>Find</b> your introductory text, and anything else you
10118
customized in your old mainCommon() routine, and move it into the
10119
showIntro() method (replacing the "TO DO!" comment in the
10120
example above).
10121
10122
<li><b>Delete</b> your mainCommon() function.  It has now been
10123
subsumed into your new gameMain object.
10124
10125
</ul>
10126
10127
<p>That's it - if you were using the standard Workbench template
10128
for mainCommon(), you're now finished.
10129
10130
<p>If you made certain kinds of changes to the template main(),
10131
mainRestore(), or mainCommon() that Workbench produced when you
10132
originally created your game, you might have to do some additional
10133
work.  These extra changes are uncommon, but check this list to make
10134
sure they don't apply to you:
10135
10136
<ul>
10137
10138
<li>Do you have anything in main() or mainRestore() beyond a simple
10139
call to mainCommon()?  If so, you'll probably have to move that code
10140
into the showIntro() method, or you might even have to override
10141
newGame() (and possibly even restoreAndRunGame()).  This is beyond the
10142
scope of this simple recipe, so please refer to the definition of
10143
GameMainDef in misc.t for full information on the new setup.
10144
10145
<li>If you customized the code in mainCommon() that restores the file
10146
specified by 'restoreFile', you'll need to override
10147
restoreAndRunGame().  You can probably just move your existing code
10148
from your old mainCommon() into a new mainGame.restoreAndRunGame()
10149
method.  Refer to the definition of GameMainDef in misc.t.
10150
10151
<li>If you player character isn't named 'me', you'll need to change
10152
the initialPlayerChar definition accordingly.
10153
10154
</ul>
10155
10156
</div>
10157
10158
<!------------------->
10159
<div class=entry>
10160
10161
<b>Minor Compatibility-breaking change:</b> A few properties that
10162
were previously in libGlobal and other library objects have been
10163
moved into the new gameMain object instead.  The relocated properties
10164
all select optional library behavior; they've been moved to gameMain
10165
to make it easier for game authors to select non-default option
10166
settings.  In the past, you had to use 'modify' to change these
10167
settings, or explicitly assign them from your startup code; now, you
10168
simply have to include any non-default option settings as property
10169
values in your gameMain object definition.
10170
10171
<p>The properties moved are:
10172
10173
<ul> 
10174
10175
<li>The former libGlobal.verboseMode is now gameMain.verboseMode.
10176
10177
<li>The former exitLister.enableStatusline is now
10178
gameMain.showExitsInStatusline.
10179
10180
<li>The former libGlobal.allowYouMeMixing is now
10181
gameMain.allowYouMeMixing.
10182
10183
<li>The former libMessages.scoreRankTable is now
10184
gameMain.scoreRankTable.
10185
10186
<li>The former libScore.maxScore is now gameMain.maxScore.  (This value
10187
is also now nil by default, since there's no reason for the library to
10188
assume a particular maximum score.)
10189
10190
</div>
10191
10192
<!------------------->
10193
<div class=entry>
10194
10195
<b>Compatibility-breaking change:</b> The format of the verbPhrase
10196
string has changed slightly for the English version of the library.
10197
Game-defined verbs might need to be adjusted to the new format.
10198
10199
<p>The change is that prepositions in a verb phrase are now grouped
10200
inside the parentheses of the "(what)" placeholders for the objects,
10201
if the prepositions go with the noun phrases.  For example, the
10202
LookIn action's verbPhrase string has changed from 'look/looking in
10203
(what)' to 'look/looking (in what)'.  The difference is subtle: by
10204
moving the preposition 'in' so that it's inside the parentheses with
10205
the direct object's "(what)" placeholder, we're telling the library
10206
that the 'in' is part of the direct object noun phrase.  Contrast
10207
this with the verbPhrase for Doff, which is now 'take/taking off
10208
(what)': this tells us that the preposition 'off' is part of the verb
10209
structure, not part of the direct object.
10210
10211
<p>How can you tell which way it goes?  There are two rules you
10212
should use to determine this.  
10213
10214
<p>First, if the preposition separates the direct and indirect
10215
objects, such as the IN in PUT X IN Y, then it <i>always</i> goes
10216
inside the indirect object phrase, hence 'put (what) (in what)'.  
10217
10218
<p>Second, for any other preposition, use the "it test": try writing
10219
the verb using 'it' in place of 'what', and ask whether it sounds
10220
right for the preposition to go before or after the 'it'.  For
10221
example, for the Doff action, TAKE IT OFF sounds right, and TAKE OFF
10222
IT is obviously wrong.  This means that the preposition 'off' belongs
10223
in the verb phrase, hence 'take off (what)'.  In contrast, for the
10224
LookIn action, LOOK IN IT sounds right, not LOOK IT IN, so the
10225
preposition goes with the direct object, hence 'look (in what)'.  If
10226
the "it test" indicates that the preposition goes <i>before</i> the
10227
'it', then the preposition is part of the direct object and thus goes
10228
<i>inside</i> the parentheses of the "(what)"; if the preposition
10229
goes <i>after</i> the 'it', then the preposition is part of the verb
10230
and goes <i>outside</i> the parentheses.
10231
10232
<p>Prepositions that go with the verb are uncommon in two-object
10233
verbs, but they do occur.  An example from the library is
10234
ConsultAbout, one form of which uses the verbPhrase 'look/looking up
10235
(what) (in what)'.  We'd write LOOK IT UP IN IT, so the preposition
10236
'up' goes after the direct object pronoun and is thus part of the
10237
verb, while the preposition 'in' goes before the indirect object
10238
pronoun and is thus part of the indirect object.  In case there's any
10239
ambiguity about whether the 'up' goes with the verb or with the
10240
indirect object, try the un-it test: we'd write LOOK UP TOPIC IN
10241
BOOK, so clearly the 'up' is not part of the indirect object, but is
10242
just part of the verb.
10243
10244
</div>
10245
10246
<!------------------->
10247
<div class=entry>
10248
10249
<b>Compatibility-breaking change:</b> The TextList classes have been
10250
removed, leaving only the more general EventList classes.  The
10251
TextList classes have been gradually converging with the EventList
10252
classes anyway, to the point where the TextList classes have become
10253
nothing more than renamed versions of the corresponding EventList
10254
classes.  Retaining the parallel set of names for otherwise equivalent
10255
classes is bad because it steepens the learning curve for new users
10256
and makes for more to remember for experienced users; so, the
10257
redundant names have now been dropped.
10258
10259
<p>Existing code will need to be scanned for occurrences of TextList,
10260
StopTextList, RandomTextList, ShuffledTextList, and SyncTextList.
10261
Replace these names with CyclicEventList, StopEventList,
10262
RandomEventList, ShuffledEventList, and SyncEventList, respectively.
10263
(Note that you can simply do a global search-and-replace to change to
10264
suffix TextList to EventList, except that you must change occurrences
10265
the TextList when it occurs as an entire word to CyclicEventList.)
10266
10267
<p>In addition, the following property names must be changed:
10268
10269
<ul>
10270
<li>textStrings to eventList
10271
<li>firstStrings to firstEvents
10272
<li>messagePercent to eventPercent
10273
<li>messageReduceAfter to eventReduceAfter
10274
<li>messageReduceTo to eventReduceTo
10275
</ul>
10276
10277
<p>If you really don't want to change your existing code, you can
10278
always use #define to create macros with the substitutions.  You
10279
really should change your code if possible, though, since using the
10280
old names is likely to create confusion as the old names recede from
10281
your memory and from the documentation.
10282
10283
</div>
10284
10285
<!------------------->
10286
<div class=entry>
10287
10288
<b>Compatibility-breaking change:</b> In ConversationReadyState,
10289
the greeting and goodbye messages have been changed.  
10290
10291
<p>First, the greetingList property is no longer used; instead, the
10292
state now looks for a HelloTopic entry and uses its response.  In
10293
addition, you can differentiate between explicit HELLO commands and
10294
implied greetings generated by other conversational commands (ASK TO,
10295
for example) by creating separate HelloTopic and ImpHelloTopic
10296
objects.  In most cases, it's not necessary to distinguish the two
10297
cases, so you can simply use a single HelloTopic to cover both cases.
10298
10299
<p>Second, the enterFromByeMsg and enterFromConvMsg methods have been
10300
removed, along with the enterFromByeList and enterFromConvList
10301
properties.  Instead, the state now looks for a ByeTopic or
10302
ImpByeTopic entry, depending on whether the conversation is ending
10303
due to an explicit GOODBYE command or due to an automatic ending (due
10304
to the other actor walking away, or due to an inactivity timeout) and
10305
uses its response.
10306
10307
<p>You should scan your existing game code for any greetingList,
10308
enterFromByeMsg, enterFromByeList, enterFromConvMsg, and
10309
enterFromConvList properties, and change them to HelloTopic,
10310
ByeTopic, and ImpByeTopic as appropriate.
10311
10312
<p>Note that both the HELLO and GOODBYE topic entries go in the
10313
ConversationReadyState, not in the InConversationState.  This is
10314
because these handlers typically describe the transition to and from
10315
the "ready" state.  A single in-conversation state could work with
10316
several "ready" states, so putting the hello/goodbye topic entries in
10317
the in-conversation state wouldn't allow any differentiation among
10318
the several "ready" state transitions.  Keeping the hello/goodbye
10319
entries in the "ready" states themselves makes this differentiation
10320
easy.  For example, this allows a "goodbye" message to say something
10321
like "Bob goes back to sweeping the porch."
10322
10323
<p>
10324
10325
</div>
10326
10327
<!------------------->
10328
<div class=entry>
10329
10330
<b>Possibly compatibility-breaking change:</b>  The internal methods
10331
that handle conversational commands in Actor have changed.  The changes
10332
are isolated to the internal methods that route the commands within
10333
and between the Actor and ActorState objects, not to the main public
10334
interfaces that game code usually uses.  Even so, since it's occasionally
10335
useful to override these internal methods, some existing game code
10336
might be affected.
10337
10338
<p>In general terms, these changes are designed to concentrate the
10339
handling of all conversational actions along a single path.  In the
10340
past, each type of conversational command was handled by its own
10341
cluster of methods, so the Actor and ActorState had a set of parallel
10342
methods for HELLO, GOODBYE, YES, NO, ASK ABOUT, ASK FOR, TELL ABOUT,
10343
SHOW TO, and GIVE TO.  This old design was intended to make it easy to
10344
override these handlers in isolation, but experience has since shown
10345
that it's much more useful to be able to override all of the handlers
10346
in concert instead.  The new design therefore consolidates all of
10347
these different conversational actions into a single method that's
10348
parameterized with the type of action.  There are still several
10349
methods because of the sequence of processing points through the Actor
10350
and ActorState, but there are no longer several clusters of methods:
10351
each of the old clusters is now a single method.
10352
10353
<p>An additional benefit of these changes is that HELLO and GOODBYE
10354
are now handled through the topic database like everything else.  This
10355
has two useful effects.  First, it means that a DefaultAnyTopic entry
10356
will now respond to a HELLO or GOODBYE along with everything else.
10357
This is highly desirable in most cases, because these defaults are
10358
usually meant to convey a blanket response to all conversational
10359
overtures.  Second, it means that it's now a bit easier to customize
10360
HELLO and GOODBYE responses: just use HelloTopic, ByeTopic, and
10361
HelloByeTopic objects as desired.
10362
10363
<p><b>Advice:</b> Because there are a lot of details to these
10364
changes, we suggest you scan your code for mentions of the affected
10365
methods, to see if your code is affected at all.  If your code
10366
doesn't define or call any of these methods, you shouldn't be
10367
affected.  The methods are:
10368
10369
<p>
10370
<ul>
10371
<li>sayToActor
10372
<li>handleConversation
10373
<li>yesNoFrom
10374
<li>answerQuestion
10375
<li>hearAbout
10376
<li>beShown
10377
<li>beGiven
10378
<li>answerRequestFor
10379
</ul>
10380
10381
<p>Now to the specific changes.
10382
10383
<p>Actor.sayToActor() has some changes to its parameters.  The
10384
'prop', 'propArgs', and 'topicListProp' parameters have been dropped,
10385
and the new 'topic' and 'convType' parameters have been added.
10386
'topic' is a special object representing the topic; the library
10387
defines the singletons helloTopicObj, byeTopicObj, yesTopicObj,
10388
and noTopicObj for the corresponding library actions.  'convType'
10389
is an object of type ConvType describing the type of action being
10390
performed.
10391
10392
<p>The new helloTopicObj and byeTopicObj singletons have
10393
been added, as mentioned above.  These are used as special topic
10394
placeholders for the HELLO and GOODBYE commands, respectively.
10395
10396
<p>The new ConvType class has been added, and singleton
10397
instances for all of the standard library conversation actions (HELLO,
10398
GOODBYE, YES, NO, ASK ABOUT, ASK FOR, etc.) have been defined.
10399
10400
<p>The 'topicListProp' and 'handler' parameters of
10401
ActorState.handleConversation() has been dropped, and the new
10402
'convType' parameter has been added.  'convType' is a ConvType
10403
object representing the conversation type.
10404
10405
<p>The 'topicListProp' parameter of
10406
ConvNode.handleConversation() has been replaced with a new 'convType'
10407
parameter, which is a ConvType object describing the conversation
10408
type.
10409
10410
<p>Actor now provides a handleConversation() method.  The
10411
ActorState will invoke this method by default when the ActorState's
10412
own handleConversation() method doesn't handle the action.  This new
10413
Actor method is in lieu of the former cluster of per-command handlers
10414
in Actor: yesnoFrom, answerQuestion, hearAbout, beShown, beGiven,
10415
answerRequestFor.
10416
10417
<p>All of the per-command handlers in Actor and ActorState
10418
have been removed: yesNoFrom, answerQuestion, hearAbout, beShown,
10419
beGiven, answerRequestFor.  These are replaced by the
10420
handleConversation() method in Actor and ActorState, as mentioned
10421
above.
10422
10423
<p>The new Actor method defaultConvResponse() is a general
10424
handler for showing the default response when a conversational action
10425
isn't otherwise handled (that is, it's not handled by any topic
10426
database entry, and the ActorState doesn't want to handle it
10427
specially).  This new method provides an easy way to show the same
10428
response for every conversational action - just override this one
10429
method, and you can show a common response for all conversation
10430
commands.  By default, this method routes looks at the convType
10431
parameter to determine the conversation type, and invokes the Actor
10432
method that provides the default response for that particular
10433
conversation type, using the same default response methods used in the
10434
past (defaultGreetingResponse, defaultGoodbyeResponse, etc).
10435
10436
<p>The ActorState object can now <i>optionally</i> define any
10437
of the default response handlers that Actor can define
10438
(defaultGreetingResponse, defaultAskResponse, etc).  When these are
10439
defined, they'll be called when the state object doesn't provide a
10440
suitable TopicEntry in its topic database.  Note that these
10441
effectively override the Actor's topic database <i>and</i> default
10442
response handlers for a given type of action.  The order of handling
10443
for a conversational action is now ConvNode, ActorState TopicEntry
10444
list, ActorState default response method, Actor TopicEntry list, and
10445
finally Actor default response method.
10446
10447
</div>
10448
10449
<!------------------->
10450
<div class=entry>
10451
10452
<b>Possibly compatibility-breaking change:</b> A change to the
10453
library's message system makes it easier to customize the default
10454
response messages for individual objects.  In the past, if you wanted
10455
to customize the message for OPEN COCONUT, say, you'd have to
10456
override the 'verify' method for the 'coconut' object's
10457
dobjFor(Open).  With this change, you can create a custom per-object
10458
message more easily: you simply define coconut.cannotOpenMsg with the
10459
custom message string.
10460
10461
<p>You can use the new message customization scheme any time the
10462
library generates a standard response message using code like this:
10463
10464
<p><pre>  dobjFor(Open)
10465
  {
10466
    verify { illogical(&amp;cannotOpenMsg); }
10467
  }
10468
</pre>
10469
10470
<p>Any time you see library code like that, you can override the
10471
default response message for that action on an individual object
10472
simply by defining the message property in your object:
10473
10474
<p><pre>  coconut: Thing
10475
    cannotOpenMsg = '{You/he} would need something sharp to do that. '
10476
  ;
10477
</pre>
10478
10479
<p>In addition to illogical(), this also works with illogicalNow(),
10480
inaccessible(), defaultReport(), defaultDescReport(), extraReport(),
10481
mainReport() reportBefore(), reportAfter(), reportFailure(), and any
10482
other verify or action reporting routines.
10483
10484
<p>Here's how this works.  In the past, when a verify, check, or
10485
action routine generated a message using a message property, the
10486
library looked up the message in the current actor's "action message
10487
object," which is usually playerActionMessages when the actor is the
10488
player character, and npcActionMessages otherwise.  Now, the library
10489
still looks there, but only <i>after</i> checking the individual
10490
objects involved in the command to see if any of them define the
10491
message property.  
10492
10493
<p>The library looks first at the direct object, then at the indirect
10494
object.  If you were to create your own custom verbs with three or
10495
more object slots, such as PUT COIN IN SLOT WITH TWEEZERS, the
10496
library would automatically continue on to those extra objects as
10497
well.  If the library finds the message property in any of these
10498
objects, it stops and uses that object as the source of the message;
10499
if it can't find the message property among these objects, the
10500
library simply falls back on the standard message object
10501
(playerActionMessage or whatever).
10502
10503
<p><b>Important:</b> As part of this change, all of the library
10504
message properties have been renamed to end in "Msg".  This affects
10505
every message property, so if you've created your own "action message
10506
object," or you've used 'modify' to change playerActionMessages
10507
and/or npcActionMessages, you'll have to do some extensive searching
10508
and replacing to add the "Msg" suffix to every message property name.
10509
Sorry about this; the proposed change was put to the TADS 3 mailing
10510
list, and no one objected.  The naming change isn't gratuitous.  The
10511
reason for the name change is that it should greatly reduce the
10512
chances of collisions between message properties and properties
10513
defined for internal use by an object.  The library itself formerly
10514
had a number of these collisions, so it was necessary to rename at
10515
least those properties; using the naming convention consistently for
10516
all of the message properties will help ensure that games don't
10517
inadvertantly introduce their own name collisions.
10518
10519
<p>There's one last detail to mention.  An object can override a
10520
message property with <i>another</i> message property.  For example,
10521
the Vaporous object in the library uses this feature:
10522
10523
<p><pre>  notWithIntangibleMsg = &amp;notWithVaporousMsg
10524
</pre>
10525
10526
<p>When a message property in an object points directly to another
10527
property, the library takes this as an indirection to another library
10528
message from the action message object.  This feature is mostly for
10529
the library's benefit, since library objects are required to get all
10530
of their messages from the action message object (to ensure that the
10531
library can be translated without rewriting entire object
10532
definitions).
10533
10534
</div>
10535
10536
<!------------------->
10537
<div class=entry>
10538
10539
<b>Minor compatibility-breaking change:</b> The Script method
10540
getState() has been renamed to getScriptState(), and the Script
10541
property curState has been renamed to curScriptState.  This change
10542
allows Script and its subclasses to be combined (with multiple
10543
inheritance) with Thing (which defines its own meaning for getState)
10544
and with Actor (which defines its own curState).  It's sometimes
10545
desirable to combine Thing or Actor with a Script subclass, because
10546
that's an easy way to attach simple scripting behavior to these
10547
objects.
10548
10549
<p>Existing game code that overrides or calls getState or curState
10550
for a Script object (including any EventList subclass) will need to
10551
be changed to use the new name.  You should scan your source code for
10552
occurrences of these names, and rename them as needed.  Note that
10553
you should <b>not</b> rename curState properties that pertain to
10554
Actor objects, since Actor.curState has <b>not</b> been renamed.
10555
10556
<p>In most cases, game code won't have any reason to override or
10557
access these script properties at all, so most game code should be
10558
unaffected by this change.  Game code usually just defines instances
10559
of the library EventList subclasses using templates, and such code
10560
won't be affected by this change.
10561
10562
</div>
10563
10564
<!------------------->
10565
<div class=entry>
10566
10567
<b>Minor compatibility-breaking change:</b> The library objects
10568
redirectTravelIn, redirectTravelOut, and redirectTravelDown have been
10569
renamed to askTravelIn, askTravelOut, and askTravelDown,
10570
respectively.  The names changes are for consistency with the naming
10571
of the new class AskConnector.
10572
10573
</div>
10574
10575
<!------------------->
10576
<div class=entry>
10577
10578
The PresentLater class has a new property, initiallyPresent, that lets
10579
you override the standard behavior of the class, which is to make the
10580
object initially absent from the game map.  This new property is set
10581
to nil by default; if you override it to true, the object will be
10582
initially present in the game, like any ordinary object.  This new
10583
property would seem to defeat the purpose of the class, but it
10584
actually extends the class to situations where an object comes and
10585
goes during the game, but starts out present.  Using PresentLater with
10586
initiallyPresent set to true, you can still use all of the
10587
PresentLater showing and hiding mechanisms, such as the key-based and
10588
conditional methods; this is often more convenient than moving objects
10589
in and out of the game map individually and manually.
10590
10591
</div>
10592
10593
<!------------------->
10594
<div class=entry>
10595
10596
The Attachable class now automatically notifies itself and each of its
10597
attachments whenever the Attachable is carried by a traveler, by
10598
calling the new method travelWhileAttached().  The method does nothing
10599
by default, but games can override it as needed to enforce conditions
10600
or carry out side effects when an attached object is moved indirectly
10601
via travel.
10602
10603
</div>
10604
10605
<!------------------->
10606
<div class=entry>
10607
10608
The Attachable class now has a way of specifying the "direction" of
10609
an attachment relationship, for the purposes of descriptive messages.
10610
Formerly, attachments were always described symmetrically: if A was
10611
attached to B, then examining A generated a status message along the
10612
lines of "A is attached to B," while examining B generated a message
10613
like "B is attached to A."  This didn't always work; "the note is
10614
attached to wall" is fine, but "the wall is attached to the note"
10615
isn't quite right.  The new feature lets you specify that the note is
10616
always said to be attached to the wall, never vice versa.
10617
10618
<p>The direction of a relationship is specified by the new Attachable
10619
method isMajorItemFor(obj).  By default, this method always simply
10620
returns nil, which means that there are no "major" items by default,
10621
which makes all attachment relationships symmetrical by default.  If
10622
you wish, you can override isMajorItemFor() so that it returns true
10623
in some cases.  When A.isMajorItemFor(B) returns true, the
10624
relationship will always be described such that B is said to be
10625
attached to A: examining A will yield "a B is attached to the A,"
10626
while examining B will show "the B is attached to an A."
10627
10628
<p>A few new methods have been added to support the new feature;
10629
these are mostly for internal use, but could potentially be used by a
10630
game to fine-tune the way attachments are listed.  The new method
10631
isListedAsAttachedTo(obj) lets the object indicate whether or not
10632
'obj' is listed among the things 'self' is attached to; by default,
10633
this returns true if 'obj' isn't permanently attached <b>and</b>
10634
'self' isn't the "major" item for 'obj'.  The new method
10635
isListedAsMajorFor(obj) is essentially the major-list counterpart: it
10636
indicates whether or not 'obj' is listed among the things attached to
10637
'self' when 'self' is described.  By default, this method returns
10638
true if 'self' <b>is</b> the "major" item for 'obj', <b>and</b>
10639
obj.isListedAsAttachedTo(self) returns true (that is, 'obj' thinks it
10640
should be listed as attached to 'self').  Finally,
10641
majorAttachmentLister returns the lister to use for the items
10642
attached to 'self' for which 'self' is the "major" item in the
10643
relationship; by default, this uses a MajorAttachmentLister instance.
10644
10645
</div>
10646
10647
<!------------------->
10648
<div class=entry>
10649
10650
The new classes Underside, RearContainer, and RearSurface make it
10651
easier to model situations where one object is behind or under
10652
another.  Underside can be used to model the space under an object, or
10653
for the bottom surface of an object.  RearContainer models the space
10654
behind an object, and RearSurface models its back surface.
10655
10656
<p>In addition to letting you set up "under" and "behind"
10657
relationships among objects initially, these new classes support the
10658
PUT UNDER and PUT BEHIND commands to let actors add new contents under
10659
and behind the objects.  (The PUT BEHIND command is also new in this
10660
release.)  An Underside can have new objects added under it with PUT
10661
UNDER, and a RearContainer or RearSurface can have new contents added
10662
with PUT BEHIND.  These commands can optionally be disallowed for a
10663
given Underside or RearContainer/RearSurface: override the properties
10664
allowPutUnder and allowPutBehind, respectively.  The new classes
10665
derive from BulkLimiter, so you can use the usual BulkLimiter
10666
properties to control the individual and total bulk allowed under and
10667
behind the objects.
10668
10669
<p>ComplexContainer has been extended to support these new classes.
10670
The new ComplexContainer property subUnderside can be set to an
10671
Underside object representing the space under or bottom surface of the
10672
complex container; the new property subRear can be set to a
10673
RearContainer or RearSurface representing the space behind or back
10674
surface of the complex container. PUT BEHIND and LOOK BEHIND commands
10675
on the complex container are routed to the subUnderside; PUT UNDER and
10676
LOOK UNDER are routed to the subRear; and both subcomponents are
10677
included in the regular LOOK AT display.
10678
10679
<p>These additions were adapted from work originally done by Eric Eve.
10680
10681
</div>
10682
10683
<!------------------->
10684
<div class=entry>
10685
10686
It's now easier to set up objects so that they're initially inside the
10687
component sub-containers of a ComplexContainer.  In the past, if you
10688
wanted to create an object in your source code so that it was
10689
initially inside a ComplexContainer's internal container, for example,
10690
you had to explicitly set the object's 'location' property, rather
10691
than using the "+" syntax.  Now, you can use the "+" syntax as long as
10692
you add a little extra information: give each contained object a new
10693
property, 'subLocation', and set it to the property of the component
10694
sub-container you want to use as the initial location.  For example,
10695
here's how you'd create a washing machine as a complex container,
10696
with a blanket inside and a laundry basket on top:
10697
10698
<p><pre>
10699
  + washingMachine: ComplexContainer 'washing machine' 'washing machine'
10700
    subContainer: ComplexComponent, Container { /* etc */ }
10701
    subSurface: ComplexComponent, Surface { /* etc */ }
10702
  ;
10703
10704
  ++ Thing 'blanket' 'blanket'
10705
    subLocation = &amp;subContainer
10706
  ;
10707
10708
  ++ Container 'laundry basket' 'laundry basket'
10709
    subLocation = &amp;subSurface
10710
  ;
10711
</pre>
10712
10713
<p>The blanket and the laundry basket are nominally directly inside
10714
the washing machine itself, according to the "+" syntax, but their
10715
'subLocation' settings ensure that they end up in the desired
10716
component sub-containers during initialization.
10717
10718
<p>Note that 'subLocation' is only intended for initialization, so the
10719
library automatically sets subLocation to nil for each object right
10720
after the initial setting is used.  This helps avoid any unpleasant
10721
surprises should the object be moved into a different ComplexContainer
10722
later on.  When you're moving objects around on the fly in your
10723
program code, there's no reason to use subLocation at all; instead,
10724
just specify the appropriate component as the explicit destination of
10725
the moveInto: <tt>towel.moveInto(washingMachine.subSurface)</tt>, for
10726
example.
10727
10728
10729
</div>
10730
10731
<!------------------->
10732
<div class=entry>
10733
10734
The Openable class has a new property, openingLister, that specifies
10735
the lister to use to display the list of items revealed when the
10736
object is opened.  By default, this is set to the
10737
openableOpeningLister object.  Individual objects can override this
10738
if they want to customize the message listing the revealed items.
10739
10740
<p>In addition, the object formerly called openingLister has been
10741
renamed to openableOpeningLister.
10742
10743
</div>
10744
10745
<!------------------->
10746
<div class=entry>
10747
10748
The new CommandTopic makes it easier to generate a response when an
10749
NPC receives a particular command.  Just create a CommandTopic, with a
10750
list of the Action classes you wish to match.  Actions are matched on
10751
class alone; if you want to match something more specific, such as
10752
matching a particular direct object of a particular action, you'll
10753
have to create a custom matchTopic() method for your CommandTopic
10754
object.  If you want to create a default response that matches any
10755
action, use a DefaultCommandTopic.
10756
10757
<p>CommandTopic works like any other TopicEntry object, so you can put
10758
these in ConvNode, ActorState, and Actor topic databases to provide
10759
responses under the specific conditions you need to match.
10760
10761
<p>As part of this change, ActorState.obeyCommand() now invokes
10762
handleConversation() to look for a response to the command, specifying
10763
the Action object as the topic and 'commandConvType' as the
10764
conversation type object.  This looks as usual in the ConvNode,
10765
ActorState, and Actor conversation topic databases for a CommandTopic
10766
to handle the response, or for a DefaultAnyTopic if there's no
10767
CommandTopic.
10768
10769
</div>
10770
10771
<!------------------->
10772
<div class=entry>
10773
10774
The parser now gives more weight to explicit owners when resolving
10775
possessives.  If a noun phrase is qualified by a possessive ("my
10776
book"), and the noun phrase is ambiguous even with the possessive
10777
qualifier (because the possessor is carrying more than one matching
10778
object), the parser will now choose an object with an explicit
10779
"owner" property over one without an explicit owner.  When the parser
10780
resolves this kind of ambiguity by choosing an explicitly owned
10781
object over one that's merely being carried, it will mark the chosen
10782
object with the UnclearDisambig flag to indicate that it's a best
10783
guess.
10784
10785
</div>
10786
10787
<!------------------->
10788
<div class=entry>
10789
10790
The library no longer treats "brightness" (the sensory intensity of
10791
light, sound, etc.) as diminishing over a "distant" containment
10792
boundary.  In the past, distance diminished brightness by one level.
10793
While this was arguably physically realistic over large distances, in
10794
practice it proved to be undesirable for the typical scales in IF
10795
settings, where "distant" is usually used to indicate that something's
10796
tens or hundreds of feet away, not miles.
10797
10798
</div>
10799
10800
<!------------------->
10801
<div class=entry>
10802
10803
The sense mechanism has a new feature that allows an object to take on
10804
its own special sensory status.  An object can use this feature to
10805
override the normal sense path mechanism and decide for itself how it
10806
appears to the senses.  The change is comprised of two new methods.
10807
10808
<p>First, when building the sense information table, the library now
10809
calls a new method, addToSenseInfoTable, on each object connected by
10810
containment to the source object.  This method by default does what
10811
the library has always done: it evaluates the temporary sense
10812
properties set up by the containment path traversal, and adds a
10813
SenseInfo object to the table based on the sense properties.  An
10814
objects can now override this method to add a table entry based on a
10815
different sensory status.
10816
10817
<p>Second, when finding the containment paths from one object to
10818
another, the library calls the new method specialPathFrom on the
10819
target object if (and <b>only</b> if) no ordinary containment path can
10820
be found.  This method can supply its own custom containment path.
10821
This allows an object to exist outside of the normal containment
10822
hierarchy but still get a chance to represent its connection to
10823
the normal containment hierarchy as it sees fit.
10824
10825
</div>
10826
10827
<!------------------->
10828
<div class=entry>
10829
10830
When a CollectiveGroup object has no location, it now takes on the
10831
sensory status of its individuals.  It will take on the "best" sense
10832
status of any individual in scope, which is the one that's most
10833
transparent and (transparencies being equal) has the highest ambient
10834
level.
10835
10836
<p>This change makes it much easier to work with CollectiveGroup
10837
objects, because it makes a CollectiveGroup as visible, audible, etc.
10838
as any of its individuals.
10839
10840
<p>Note that this change doesn't affect CollectiveGroup objects that
10841
have a normal location.  These objects already participated in the
10842
sensory model in the normal manner, and will continue to do so.  This
10843
change only affects group objects with no location.
10844
10845
</div>
10846
10847
<!------------------->
10848
<div class=entry>
10849
10850
The handling of the "catch-all" Default handlers has changed
10851
slightly.  The sequence of processing is now as follows:
10852
10853
<p>
10854
<ul>
10855
<li>The iobjFor(All) and dobjFor(All) handlers run first, if defined.
10856
<li>The iobjFor(Default) and dobjFor(Default) handlers run next, <i>if</i>
10857
they "override" the verb-specific handlers.
10858
<li>The iobjFor() and dobjFor() handlers for the specific verb run next,
10859
<i>unless</i> the corresponding Default handlers override them
10860
</ul>
10861
10862
<p>In the past, the 'verify', 'check', and 'action' methods for the
10863
Default handlers were called <i>in addition to</i> any verb-specific
10864
versions of the methods.  For example, if an object defined a
10865
dobjFor(Default) with an action() method, and the player entered an
10866
OPEN command on the object, the Default action handler ran, and then
10867
the dobjFor(Open) action() method <i>also</i> ran.  In most cases,
10868
this made no difference, because the base Thing class doesn't even
10869
define action() or check() handlers for most verbs, since it
10870
disallows most verbs in the verify() stage.
10871
10872
<p>With this change, the Default handlers now run <i>instead of</i> the
10873
verb-specific handlers, when the Default handlers run at all.  The
10874
rules about when Default handlers override verb-specific handlers,
10875
and vice versa, haven't changed.  A Default handler still overrides
10876
any verb-specific handler inherited from a base class, and any
10877
verb-specific handler defined in the same class as the Default
10878
handler or in any subclass still overrides that Default handler.
10879
10880
<p>Note that the relative order of the All and Default handlers has
10881
been reversed: the All handler now always runs first.  This makes the
10882
sequence of methods proceed from most general to most specific.
10883
10884
</div>
10885
10886
<!------------------->
10887
<div class=entry>
10888
10889
If an 'exit' occurs within a PreCondition object's
10890
checkPreCondition() method, it's now treated as a failure of the
10891
enclosing action that invoked the precondition.  The normal pattern
10892
that most preconditions use is as follows: first, evaluate if the
10893
condition is met; second, if the condition isn't met, try an
10894
appropriate implied action to try to bring it into effect; third,
10895
re-test the condition to see if the implied action did what it was
10896
meant to; and fourth, if the condition still doesn't apply, use
10897
'exit' to terminate the triggering action.  It's this use of 'exit'
10898
that's now interpreted as a failure of the enclosing action.
10899
10900
<p>Note that this doesn't apply if 'exit' is used within a nested
10901
implied action; this only applies if 'exit' is used within the
10902
precondition's checkPreCondition() method itself.
10903
10904
</div>
10905
10906
<!------------------->
10907
<div class=entry>
10908
10909
The library now defines a template for the Achievement class, taking
10910
a double-quoted string for the achievment's description text.
10911
10912
</div>
10913
10914
<!------------------->
10915
<div class=entry>
10916
10917
The new function finishGameMsg() makes it easier to show one of the
10918
conventional end-of-game messages, such as "*** YOU HAVE DIED ***" or
10919
"*** YOU HAVE WON ***".  This function takes two parameters: a
10920
message specifier, and a list of extra finishing options.  The extra
10921
options are the same as for the existing function finishGame().  
10922
10923
<p>The message specifier can be one of several standard, pre-defined
10924
objects, or it can simply be a string to display.  The pre-defined
10925
object ftDeath, ftVictory, ftFailure, and ftGameOver display messages
10926
for death of the player character ("YOU HAVE DIED"), victory ("YOU
10927
HAVE WON"), failure ("YOU HAVE FAILED"), and simply "game over",
10928
respectively.  Alternatively, you can make up your own messages for
10929
unconventional cases ('YOU HAVE SUFFERED A FATE WORSE THAN DEATH',
10930
say) simply by specifying a string.  Your string will be displayed
10931
surrounded by "***" sequences to yield the conventional formatting,
10932
or with other sequences that might vary by language.  You can also
10933
pass nil as the message specifier, in which case no message at all
10934
is displayed.
10935
10936
</div>
10937
10938
<!------------------->
10939
<div class=entry>
10940
10941
The value of gameMain.maxScore (formerly libScore.maxScore) is now
10942
allowed to be nil.  In addition, the default value in GameMainDef is
10943
now nil.  When this value is nil, the SCORE and FULL SCORE commands
10944
simply won't mention a maximum score for the game.
10945
10946
<p>If your game has complex scoring that makes it difficult or
10947
impossible to state a maximum possible score, or if you simply don't
10948
want to give this information to the player, simply set maxScore to
10949
nil in your gameMain object.  The library uses nil as the default
10950
because there's no reason for the library to assume that a game will
10951
have a particular maximum score (the library formerly used a default
10952
value of 100, but this was overly presumptuous).
10953
10954
</div>
10955
10956
<!------------------->
10957
<div class=entry>
10958
10959
The library's scoring system has a new, optional usage style that
10960
provides two benefits.  First, it lets you define the number of points
10961
an Achievement is worth as part of the Achievement object, better
10962
encapsulating the information about the Achievement.  Second, the
10963
library can use this new information to automatically compute the
10964
maximum possible score in the game, saving you the trouble of figuring
10965
this out manually (and of keeping the stated maximum in sync with the
10966
game as you make changes).
10967
10968
<p>If you explicitly set the maxScore property in your gameMain object,
10969
the library will <b>not</b> automatically compute the maximum score.
10970
Your explicit maxScore setting always overrides the computed value.
10971
10972
<p>To take advantage of the new capabilities, simply define the new
10973
'points' property for each Achievement object you create.  Then,
10974
rather than calling addToScore() or addToScoreOnce(), both of which
10975
take a parameter specifying the number of points to award, call the
10976
new Achievement methods awardPoints() or awardPointsOnce() instead.
10977
For example, suppose you have some existing code that looks like
10978
this:
10979
10980
<p><pre>
10981
  vase: Thing
10982
    handleBreakage()
10983
    {
10984
      // ... do the real work here...
10985
10986
      scoreMarker.addToScoreOnce(10);
10987
    }
10988
10989
    scoreMarker: Achievement { "breaking the base" }
10990
  ;
10991
</pre>
10992
10993
<p>This code defines a nested object called 'scoreMarker' to describe
10994
the scoring item, and the 'handleBreakage' method awards the Achievement
10995
object, assigning it 10 points in the score.  Using the new style,
10996
you'd change the code above to look like this instead:
10997
10998
<p><pre>
10999
  vase: Thing
11000
    handleBreakage()
11001
    {
11002
      // ... do the real work here...
11003
11004
      scoreMarker.awardPoints();
11005
    }
11006
11007
    scoreMarker: Achievement { +10 "breaking the base" }
11008
  ;
11009
</pre>
11010
11011
<p>The "+10" in the nested Achievement definition assigns the object a
11012
value of 10 in its 'points' property (using a template defined in
11013
adv3.h), indicating that the item is worth 10 points in the score.
11014
Rather than specifying this in the code that awards the Achievement,
11015
we define it as part of the Achievement object itself.  The code that
11016
awards the points doesn't need to specify the number of points; it
11017
just calls the awardPoints() method of the Achievement object, which
11018
awards the points defined in the object.  This makes the code easier
11019
to read, since you can see the description of the scoring item and the
11020
number of points it's worth in one place.
11021
11022
<p>To take advantage of the library's automatic computation of the
11023
maximum possible score, you have to follow a few rules:
11024
11025
<ul>
11026
11027
<li>Use <b>only</b> Achievement objects to award points.  Never
11028
call addToScore() with a string value to award an ad hoc scoring item.
11029
11030
<li>Set the 'points' property of each of your Achievement objects
11031
to the number of points the item is worth.
11032
11033
<li>If an Achievement can be scored more than once, <b>also</b> set
11034
the 'maxPoints' property to the maximum number of points the item will
11035
contribute to the score.  This is usually just 'points' times the number
11036
of times the item can be awarded.
11037
11038
<li>Only define Achievement objects statically.  Never use 'new
11039
Achievement' to create an Achievement dynamically.  (If you create new
11040
Achievements dynamically, the library won't know about them at
11041
start-up time, obviously, so it can't count their contributions to the
11042
maximum score.)
11043
11044
<li>Always award Achievements through their awardPoints() or
11045
awardPointsOnce() methods.  (This ensures that each Achievement is
11046
scored with the number of points specified in its 'points' property.)
11047
11048
<li>Achievements can't be mutually exclusive.  That is, there must
11049
exist at least one solution of the game in which every Achievement
11050
object is awarded.  (If you have Achievement objects that represent
11051
different solutions to the same puzzle, so that only one of these
11052
achievements can actually be awarded in any given traversal of the
11053
game, the library would incorrectly count the score contributions of
11054
all of the alternatives in the maximum score.  The correct maximum
11055
would count only the single highest score among the alternatives.  The
11056
library has no way of expressing mutual exclusion among Achievements,
11057
so if your game has such a situation, you'll need to set
11058
libScore.maxScore manually.)
11059
11060
</ul>
11061
11062
<p>If you follow these rules, the library will accurately compute the
11063
maximum score value, so you don't need to bother figuring out how many
11064
points are in the game yourself, and you don't need to worry about
11065
initializing libScore.maxScore in your game's start-up code.
11066
11067
<p>If your game can't follow the rules above (because you have
11068
alternative solutions to puzzles that assign different scores, for
11069
example, or because your game has alternative paths with different
11070
maximum scores), you'll need to figure the maximum score manually,
11071
and set the property 'maxScore' to this value in your 'gameMain'
11072
object.  Explicitly setting gameMain.maxScore in your code will
11073
override the library's automatic computation.
11074
11075
</div>
11076
11077
<!------------------->
11078
<div class=entry>
11079
11080
The finishGame() and finishGameMsg() functions now display the
11081
current score (using the same message that the SCORE command normally
11082
displays) if the finishOptionFullScore option is in the extra options
11083
list.  In fact, these functions will announce the score if any extra
11084
option has the property showScoreInFinish set to true;
11085
finishOptionFullScore has this option set to true, so including it in
11086
the extra options list causes the score to be announced.  If you want
11087
the end-of-game announcement to include the score, but you don't want
11088
to offer the FULL SCORE option, you can include finishOptionScore in
11089
the extra options list; this is an "unlisted" option, so it doesn't
11090
add anything to the list of offered option list, but it does cause
11091
the end-of-game announcement to include the score.
11092
11093
</div>
11094
11095
<!------------------->
11096
<div class=entry>
11097
11098
Actor.holdingDesc (which provides the default description of what an
11099
actor is holding as part of processing an Examine action on the
11100
actor) now uses pretty much the same handling that Thing uses when it
11101
lists the contents of an object.  The only difference is that
11102
Actor.holdingDesc still uses the special holdingDescInventoryLister
11103
as the contents lister.  One important consequence of this change is
11104
that examining an actor marks the actor's contents as having been
11105
seen by the player character, just as examining an ordinary object
11106
marks the object's contents as seen.  Another is that the scope of
11107
objects included in the listing is limited to objects the
11108
point-of-view actor can actually see.  In the past, the examined
11109
actor listed everything in "inventory scope," which includes objects
11110
that are directly held even if they're not currently visible; this is
11111
correct for an inventory listing from the point of the view of the
11112
actor taking the inventory (because the actor can presumably identify
11113
directly held items by feel, even in the dark), but the new
11114
sight-only behavior is more appropriate for examining another actor.
11115
11116
<p>This change also adds a new Thing method examineListContentsWith().
11117
This is simply a service method that performs the bulk of what
11118
Thing.examineListContents() did before, but is parameterized by
11119
a lister to use to generate the listing.
11120
11121
</div>
11122
11123
<!------------------->
11124
<div class=entry>
11125
11126
The new class AskConnector makes it easy to define a directional
11127
connection when the direction is ambiguous.  For example, suppose
11128
that you have two doors leading north, and you don't want to use the
11129
traditional trick of distinguishing the doors' respective directions
11130
as northeast and northwest.  (If you had ten doors leading north
11131
instead of two, the traditional northeast/northwest trick wouldn't
11132
help anyway.)  If the player types NORTH, you would like the parser
11133
to ask which door to use.
11134
11135
<p>AskConnector makes this easy.  Simply define the room's 'north' as
11136
an AskConnector object, and set the AskConnector instance's property
11137
'travelAction' to 'GoThroughAction'.  The connector, when invoked for
11138
travel, will try running the GoThroughAction, but with a missing
11139
direct object; this will make the parser ask the player which door to
11140
use with the usual prompt for a missing object: "What do you want to
11141
go through?"
11142
11143
<p>If the direction has a specific set of possible objects, as in
11144
our example of two doors leading north, you can further refine the
11145
parser's question by specifying the 'travelObjs' property.  Set this
11146
to a list of the possible direct objects for the action.  If you set
11147
this property, you should also set 'travelObjsPhrase' to a string
11148
giving the noun phrase to use in disambiguous questions: in our
11149
example, we might set this to 'door', so that the question becomes
11150
"Which door do you mean...?".
11151
11152
</div>
11153
11154
<!------------------->
11155
<div class=entry>
11156
11157
The English library now provides a default verbPhrase for the
11158
TravelVia action ('use/using (what)', which is pretty vague, but
11159
TravelVia is fairly vague itself).  This lets the parser generate
11160
usable messages in cases where a TravelVia action elicits a parser
11161
prompt, such as when using TravelVia in askForDobj().
11162
11163
</div>
11164
11165
<!------------------->
11166
<div class=entry>
11167
11168
TravelPushable has several small changes.
11169
11170
<p>First, TravelPushable.movePushable() now uses moveIntoForTravel()
11171
to move the object, rather than moveInto().  This corrects a problem
11172
that occurred when the starting and destination locations were
11173
connected by a sense connection (such as a distance connector).
11174
11175
<p>Second, movePushable() and describeMovePushable() each now take an
11176
additional argument giving the connector being traversed.
11177
11178
<p>Third, the new method beforeMovePushable() gives the pushable
11179
object a chance to do any necessary work just before the travel takes
11180
place.  This is especially useful for adding a message describing
11181
anything special that happens when pushing the object out of its
11182
current location.  By default, this routine does nothing.
11183
11184
</div>
11185
11186
<!------------------->
11187
<div class=entry>
11188
11189
The new Traveler methods canTravelVia() and explainNoTravelVia() allow
11190
a traveler to disallow travel via a particular connector and/or to a
11191
particular destination.  These new methods essentially provide a
11192
complement of the "travel barrier" mechanism, which allows a connector
11193
to disallow travel by a particular traveler.  The new methods are
11194
useful becuase it's often more convenient to tie a travel condition to
11195
the traveler than to the connector.  For example, you might want to
11196
implement a condition that prohibits a particular actor from going
11197
outside; you could do this by defining a canTravelVia() method on the
11198
actor that returns nil if the destination is an OutdoorRoom.
11199
11200
</div>
11201
11202
<!------------------->
11203
<div class=entry>
11204
11205
The new BasicLocation methods enteringRoom(traveler) and
11206
leavingRoom(traveler) make it more convenient to write code that
11207
responds to an actor's arrival into or departure from a room.  These
11208
methods are called from travelerArriving() and travelerLeaving(),
11209
respectively; they differ only in that (1) they have simpler
11210
parameter lists, leaving out information that frequently isn't needed
11211
to write an arrival/departure event handler, and (2) the base class
11212
implementations don't do anything, so there's no need to use
11213
'inherited' to inherit up the base class behavior.  These new methods
11214
are purely for convenience, to make the very common task of writing
11215
arrival/departure event handlers a little less work.
11216
11217
</div>
11218
11219
<!------------------->
11220
<div class=entry>
11221
11222
The new class ContainerDoor makes it easy to create a door for a
11223
container, if you want the door to act like a separate object in its
11224
own right.  This works with the ComplexContainer class: create a
11225
parent as a ComplexContainer, and inside it create a ContainerDoor
11226
and the normal secret actual Container.  The door will redirect
11227
commands like open, close, lock, and unlock to the secret inner
11228
container, but will still appear as a separate object.
11229
11230
</div>
11231
11232
<!------------------->
11233
<div class=entry>
11234
11235
In the past, the base TravelConnector methods describeArrival() and
11236
describeDeparture() simply showed the most generic travel messages
11237
("Bob is leaving the area").  This meant that replacing a simple room
11238
connection with a TravelMessage connector meant giving up the
11239
directional message that a normal room connection generated ("Bob is
11240
leaving to the east").
11241
11242
<p>Now, the directional message is the default in the base
11243
TravelConnector class.  If there's a direction property linked to the
11244
connector from the origin (for a departure) or destination (for an
11245
arrival), the base TravelConnector messages will now show the
11246
directional version of the message.  The generic, non-directional
11247
message will only be shown when no directional link can be found.
11248
Note that this doesn't affect the more specific types of connectors
11249
and their custom messages, so stairs will still say "Bob goes up the
11250
stairs," doors will still say "Bob leaves through the wooden door,"
11251
and so on.
11252
11253
</div>
11254
11255
<!------------------->
11256
<div class=entry>
11257
11258
The new TravelConnector method isConnectorPassable() indicates whether
11259
or not a traveler can pass through the connector.  This can be used in
11260
game code that probes the map to determine if a connector can be
11261
traversed in its current state.
11262
11263
</div>
11264
11265
<!------------------->
11266
<div class=entry>
11267
11268
In the past, the noTravel object, and the NoTravelMessage and
11269
FakeConnector classes, incorrectly displayed their special messages on
11270
attempted travel even when it was dark in the room.  In the dark, the
11271
"dark travel" message should take precedence.  This has been
11272
corrected.  (The problem was that these classes overrode the
11273
dobjFor(TravelVia) check() method to bypass the normal darkness check.
11274
The unnecessary override has been removed, so the standard darkness
11275
check is now made, so the dark-travel message is now shown instead of
11276
any special message.)
11277
11278
</div>
11279
11280
<!------------------->
11281
<div class=entry>
11282
11283
The BasicLocation methods getTraveler() and getPushTraveler() have
11284
been renamed and moved into Thing.  These methods are now called
11285
getLocTraveler() ("get location traveler") and getLocPushTraveler()
11286
("get location push traveler"), respectively.
11287
11288
<p>This change is necessary to allow actors to hold other actors, and
11289
to allow intermediate containers within rooms (that is, to allow a
11290
Room to hold an arbitrary Thing subclass, which in turn holds a
11291
NestedRoom).  Actor has methods with the names getTraveler() and
11292
getPushTraveler(), but these methods have a different purpose than the
11293
old BasicLocation methods: the Actor methods get the traveler when the
11294
actor is initiating the travel, and the old BasicLocation methods get
11295
the actual traveler when a traveler within the location initiates
11296
travel.  The use of the same name created a conflict between these
11297
different purposes, so one or the other set had to be renamed.  In
11298
addition, limiting these methods to BasicLocation prevented ordinary
11299
Things from holding actors who could travel; adding them to Thing
11300
corrects this.
11301
11302
</div>
11303
11304
<!------------------->
11305
<div class=entry>
11306
11307
The logic in Vehicle.getTraveler() that determines whether to move
11308
the vehicle or the traveler within the vehicle has changed slightly.
11309
Rather than basing the decision on travel barriers, the routine now
11310
moves the traveler rather than the vehicle only if the connector is
11311
contained within the vehicle - that is, the connector leads somewhere
11312
from inside the vehicle.  The connector is considered to be inside
11313
the vehicle if (1) it's a physical object (a Thing) that's inside the
11314
vehicle, or (2) one of the direction properties of the vehicle is set
11315
to the connector.  (The old logic had the undesirable side effect of
11316
implicitly removing the traveler from the vehicle if the vehicle
11317
couldn't cross a barrier, which was really too automatic.)
11318
11319
</div>
11320
11321
<!------------------->
11322
<div class=entry>
11323
11324
In the past, the way push-travel actions was handled caused a problem
11325
in certain cases involving remapping of actions.  The problem showed
11326
up most readily with StairwayUp and StairwayDown objects;
11327
specifically, PUSH x DOWN acted differently than PUSH x DOWN y, where
11328
y was a StairwayUp or StairwayDown and the room's 'up' or 'down'
11329
pointed to y.  These commands obviously should have been equivalent.
11330
11331
<p>Stairways were the only library objects that exposed the problem,
11332
but it was possible to define your own objects with the same bad
11333
behavior.  In general, the problem occurred whenever a two-object
11334
push-travel action (PUSH x UP y, PUSH x THROUGH y, PUSH x INTO y,
11335
etc.) was attempted, <i>and</i> the indirect object's handler for the
11336
corresponding travel action (ClimbUp, GoThrough, Enter, etc.) was
11337
defined using asDobjFor(), <i>and</i> the handler for the target
11338
action of the asDobjFor() was itself defined using a remapTo().
11339
11340
<p>The problem has been fixed, so any two-object push-travel action
11341
should now be handled equivalently to the corresponding one-object
11342
(directional) push-travel action on the same travel connector.
11343
11344
</div>
11345
11346
<!------------------->
11347
<div class=entry>
11348
11349
The Chair, Bed, and Platform classes can now <i>all</i> allow
11350
standing, sitting, and lying on the object.  In the past, Chair only
11351
allowed sitting, Bed allowed lying and sitting, and Platform allowed
11352
all three.  The set of postures allowed can now be customized for
11353
each individual object.
11354
11355
<p>The new property allowedPostures contains a list of the postures
11356
that the object allows.  By default, Chair allows sitting and
11357
standing, and Bed and Platform allow sitting, standing, and lying.
11358
You can override allowedPostures for an individual Chair, Bed, or
11359
Platform object to add or remove allowed postures.  When a posture
11360
isn't in the allowed list, it will be ruled as "illogical" in the
11361
verification stage.
11362
11363
<p>In addition, the new property obviousPostures contains a list of
11364
the postures that are "obvious" for the object; these are the
11365
postures that are most natural for the object.  The obvious postures
11366
are enumerated separately from the allowed postures to control
11367
defaulting: if a posture is allowed but not obvious for an object,
11368
then the corresponding command will be ruled as "nonObvious" in the
11369
verify stage, ensuring that the command will only be accepted if
11370
stated explicitly (that is, the player will be able to perform the
11371
command, but the parser won't automatically guess the command based
11372
on incomplete information from the player).  By default, it's obvious
11373
to sit on a chair, to sit or lie on a bed, and to sit, lie, or stand
11374
on a platform.
11375
11376
<p>The three separate classes are still three separate classes for a
11377
couple of reasons.  First, each one has a primary, "natural" posture
11378
associated with it: sitting on a chair, lying on a bed, standing on a
11379
platform.  This primary posture is the one that the library will
11380
assume for implied actions and incomplete commands.  Second, Platform
11381
differs from the other two in that objects dropped while standing on
11382
a platform land on the platform, whereas objects dropped while on a
11383
chair or bed land in the enclosing room.
11384
11385
<p>Note that a posture that isn't allowed by allowedPostures will
11386
be treated as illogical.  If you want to create an object for which
11387
a given posture makes physical sense, but isn't allowed for some
11388
other reason (character motivation constraints, for example), you
11389
should include the posture in allowedPostures and then disallow the
11390
corresponding command using the check() routine.
11391
11392
</div>
11393
11394
<!------------------->
11395
<div class=entry>
11396
11397
NestedRoom now defines 'out' to use the special 'noTravelOut'
11398
connector, which will automatically treat an OUT command as a GET OUT
11399
OF command while in the nested room.  Without this, the 'noTravelOut'
11400
would typically be "inherited" from the enclosing room anyway, but
11401
not always: if the enclosing room defined its own OUT, the nested
11402
room would pick up that one instead, which isn't usually appropriate
11403
when within a nested room.  This change ensures that nested rooms
11404
behave consistently even when nested within rooms with their own
11405
explicit 'out' connections.
11406
11407
</div>
11408
11409
<!------------------->
11410
<div class=entry>
11411
11412
The HighNestedRoom class now prohibits exiting the room, by default.
11413
It does this by setting the exitDestination property to nil; this
11414
indicates that the room has no natural exit location, so it's not
11415
possible to leave it.  HighNestedRoom generates an appropriate
11416
message ("It's too long a drop to do that from here") when an
11417
attempt to exit the location fails.
11418
11419
<p>The base NestedRoom now checks, in the GetOutOf action's check()
11420
handler, that there is a non-nil exitDestination.  If there's not a
11421
valid exit destination, the check() handler calls the new method
11422
cannotMoveActorOutOf() to display an appropriate message, then
11423
terminates the command with 'exit'.
11424
11425
</div>
11426
11427
<!------------------->
11428
<div class=entry>
11429
11430
By default, NestedRoom now uses the new travel connector nestedRoomOut
11431
for its "out" link, rather than noTravelOut as it did in the past.
11432
The nestedRoomOut connector works just like noTravelOut, except that
11433
nestedRoomOut is "apparent" to characters, so it shows up in the EXITS
11434
list.  Since OUT is usually a valid travel command while in a nested
11435
room (the command exits the nested room), it makes sense to list OUT
11436
explicitly as a possible direction while in a nested room.  To
11437
override this for a particular nested room, just set 'out' to
11438
noTravelOut; to change this behavior for all nested rooms, do the same
11439
thing with 'modify NestedRoom'.
11440
11441
</div>
11442
11443
<!------------------->
11444
<div class=entry>
11445
11446
The new Floorless class is a mix-in that can be combined with any
11447
other type of Room class to create a floorless version of the room.
11448
Mix Floorless in ahead of the Room base class in the superclass list
11449
of the room you're creating; Floorless will, among other things,
11450
subtract any default floor/ground object from the base room's
11451
roomParts list.
11452
11453
<p>The existing FloorlessRoom class has been retained, but is now
11454
simply a convenience class that combines Floorless and Room.  This
11455
provides the same behavior as the old FloorlessRoom class, so existing
11456
code should not be affected.
11457
11458
</div>
11459
11460
<!------------------->
11461
<div class=entry>
11462
11463
Some fine-tuning has been applied to announcements for cascading
11464
implied actions in certain cases.  When a series of nested implied
11465
actions fails, the parser now announces only the first of the series.
11466
For example, in the past, if a travel action initiated an OPEN DOOR
11467
which initiated an UNLOCK DOOR which failed, the parser showed
11468
something like this: (first trying to unlock the door and then open
11469
it).  The parser now shows only this: (first trying to unlock the
11470
door).
11471
11472
<p>The reason for dropping the extra announcements is that they don't
11473
really tell the player anything useful, so they're just unnecessary
11474
verbosity.  Because of the recursive relationship of the implied
11475
action in these cases, the first action is nested in the second,
11476
which is nested in the third, and so on; so the second and subsequent
11477
actions all failed as a direct result of the first one failing (in
11478
our example, the OPEN fails because it requires the UNLOCK to
11479
succeed, so when the UNLOCK fails the OPEN must also fail).  This
11480
means that we never actually get around to trying the second and
11481
subsequent actions; when the first action fails, we give up on
11482
trying any of the others.  The only thing they tell the player is
11483
why the failed action was attempted at all (in our example, the
11484
implied OPEN explains why we're attempting the implied UNLOCK).
11485
But the rationale in these cases is almost always obvious to the 
11486
player, so even this isn't a very good reason to keep the extra
11487
announcements.
11488
11489
<p>This behavior can be controlled via
11490
implicitAnnouncementGrouper.keepAllFailures.  The property is nil
11491
by default; to list the entire stack of failures for these cases,
11492
change it to true.
11493
11494
</div>
11495
11496
<!------------------->
11497
<div class=entry>
11498
11499
The extra "testing" step for opening Lockable objects has been
11500
removed.  This extra step was introduced in 3.0.6m to make the cascade
11501
of implied actions more plausible for these cases, but the extra
11502
verbosity was really too much, so it's been removed in the interest
11503
of simplicity.
11504
11505
<p>Instead, a Lockable now tests a new method, autoUnlockOnOpen(); if
11506
this returns true, then OPEN implies UNLOCK, otherwise it does not.
11507
This means that, if autoUnlockOnOpen returns nil, and the object is
11508
locked, then an OPEN command will simply fail with an error message
11509
("the door seems to be locked"), and the player will have to enter an
11510
explicit UNLOCK command.
11511
11512
<p>The new autoUnlockOnOpen() method is defined as follows:
11513
11514
<ul>
11515
11516
<li>For Lockable, the method returns the value of the lockStatusObvious
11517
property.  This means that OPEN implies UNLOCK if the lock status is
11518
readily observable, and requires a separate, explicit UNLOCK if not.
11519
11520
<li>For KeyedLockable, the method returns true if the inherited value
11521
is true, OR if the actor is carrying a known key for the object.  By
11522
default, a KeyedLockable automatically remembers keys as known once
11523
they're successfully used, so once an object is successfully unlocked
11524
with a key, an OPEN command will automatically imply UNLOCK on
11525
subsequent attempts, as long as the actor is carrying the same key.
11526
This is a concession to playability, in that it eliminates the need
11527
to spell out every step of operating a door or other keyed lockable
11528
after the first time through, but it's also arguably more realistic:
11529
the actor knows from experience how to operate the door, so we can
11530
see the automatic UNLOCK as merely leaving some boring details out of
11531
the narration.
11532
11533
</ul>
11534
11535
<p>Some authors might always prefer the automatic UNLOCK to forcing a
11536
player to type a separate UNLOCK command for objects with non-obvious
11537
locking status.  Which way you prefer is a matter of taste.  On the
11538
one hand, the extra UNLOCK command is a little annoying to players,
11539
and is exactly the sort of thing the precondition mechanism was
11540
created to avoid.  On the other hand, the automatic UNLOCK is weird
11541
when the lock status isn't apparent, because until the OPEN fails, we
11542
have no way of knowing that the object was locked in the first place
11543
and thus no reason to try the implied UNLOCK; it's an instance of the
11544
parser revealing game-state information that the player character
11545
isn't supposed to know.  It also could be seen as actually detracting
11546
from playability by making the game do too much automatically, taking
11547
away a certain amount of control from the player (the player could
11548
think: "I didn't even know that door was locked; if I had, I wouldn't
11549
have tried to unlock it right now.")
11550
11551
<p>By default, the library implements the more realistic but also
11552
more tedious behavior, requiring a separate UNLOCK to OPEN a locked
11553
object whose lock status isn't obvious.  If you prefer to make UNLOCK
11554
automatic on OPEN for a given object, simply override
11555
autoOpenOnUnlock() to return true unconditionally for that object; if
11556
you prefer to make UNLOCK automatic for all objects, modify Lockable
11557
to make autoOpenOnUnlock() return true in all cases.
11558
11559
</div>
11560
11561
<!------------------->
11562
<div class=entry>
11563
11564
The implied command behavior of keyed-lockable objects has been
11565
changed slightly.  In the past, attempting to OPEN a keyed-lockable
11566
triggered an implied UNLOCK, which asked for a key.  Thus, a command
11567
like OPEN DOOR, or even GO NORTH, could be answered with a question
11568
("What do you want to unlock it with?").  This was a little awkward
11569
because the player never actually said in so many words that they
11570
wanted to unlock the door.  Now, keyed-lockable objects simply
11571
point out that a key is required to open the lock:
11572
11573
<p><pre>
11574
  &gt;go north
11575
  (first trying to unlock the iron door)
11576
  You need a key to unlock the door.
11577
</pre>
11578
11579
<p>Note, however, that if the actor knows which key to use, and one
11580
of the known keys is in sight, then the command will be allowed to
11581
proceed implicitly.  In these cases, it won't be necessary to ask for
11582
the key, since the actor's knowledge of the key allows it to be
11583
supplied automatically as a default.
11584
11585
</div>
11586
11587
<!------------------->
11588
<div class=entry>
11589
11590
The Keyring class now follows the normal Thing conventions for
11591
mentioning the contents of the keyring.  Formerly, Keyring.desc
11592
generated the list of contents, using a lister defined in the property
11593
'examineLister'.  Now, Keyring has no separate 'desc' method;
11594
instead, the listing is generated by the standard Examine code
11595
inherited from Thing, and the 'examineLister' property has been
11596
renamed to 'descContentsLister' to accommodate the inherited
11597
Thing methods.
11598
11599
</div>
11600
11601
<!------------------->
11602
<div class=entry>
11603
11604
The new class CustomImmovable makes it easy to create an Immovable that
11605
uses a single customized message to respond to all attempts to move
11606
the object.  Just override cannotTakeMsg, and the "move" and "put in"
11607
messages will use the same message.  The new class CustomFixture does
11608
the same thing for Fixture.
11609
11610
</div>
11611
11612
<!------------------->
11613
<div class=entry>
11614
11615
The new class FueledLightSource abstracts some of the functionality
11616
that was formerly in Candle, to create a base class for objects that
11617
provide light using a limited fuel supply.  The new base class
11618
doesn't assume that it's something that burns, as Candle does, so you
11619
can use the new class to create things like limited-use flashlights.
11620
Candle is now based on the new class.  This change shouldn't affect
11621
any existing game code; the implementation of Candle has merely been
11622
rearranged internally to the library, so no changes should be
11623
required to existing code.
11624
11625
<p>An additional improvement in the new FueledLightSource class is
11626
that the fuel source is no longer assumed to be the object itself.
11627
This lets you model the fuel source as a separate object; for example,
11628
you could use a separate battery object as the fuel source for a
11629
flashlight, allowing a character in the game to swap out a dead
11630
battery for a new one.  Simply override the 'fuelSource' property
11631
of your FueledLightSource object to specify the object that provides
11632
the fuel.  By default, the fuel source is still 'self', so Candle
11633
objects in existing source code won't need any changes.
11634
11635
</div>
11636
11637
<!------------------->
11638
<div class=entry>
11639
11640
The tryMakingRoomToHold method in Actor now checks each object it's
11641
about to move into a "bag of holding" to make sure the object that's
11642
to be held isn't inside the object to be moved.  This ensures that the
11643
attempt to make more room to hold things doesn't inadvertantly move
11644
the object to be held out of reach, defeating the purpose of making
11645
room to hold it.  This change ensures that the object to be held
11646
stays where it is, since all of its containers stay where they are.
11647
11648
</div>
11649
11650
<!------------------->
11651
<div class=entry>
11652
11653
UnlistedProxyConnector.ofKind now returns true if the caller is
11654
asking about UnlistedProxyConnector, and <i>also</i> returns true if
11655
the caller is asking about the class of the underlying connector.
11656
This makes a proxy look like its underlying connector and also like a
11657
proxy, which is consistent with the rest of its behavior.
11658
11659
</div>
11660
11661
<!------------------->
11662
<div class=entry>
11663
11664
The new DefaultTopic property 'excludeMatch' can be set to a list of
11665
topics (Thing or Topic objects) to exclude from the catch-all match.
11666
By default, this is just an empty list, so nothing is excluded.
11667
Individual DefaultTopic objects can provide a list of objects to
11668
exclude from the catch-all.  This is useful when you're creating a
11669
DefaultTopic for a ConvNode or ActorState, but you want one or more
11670
specific topics to be referred to the enclosing topic database for
11671
handling.  By including the topics in the excludeMatch list, you
11672
ensure that they won't be caught in the catch-all DefaultTopic, which
11673
will let them propagate to the enclosing topic database.
11674
11675
</div>
11676
11677
<!------------------->
11678
<div class=entry>
11679
11680
ConvNode.npcContinueConversation() now returns true if anything was
11681
displayed in the course of the method, nil if not.  This lets a caller
11682
determine if the NPC actually had anything to say.
11683
11684
<p>ActorState.takeTurn() now uses this information to consider the
11685
NPC to have finished its turn if the ConvNode added a conversational
11686
message.  In the past, merely having a non-nil ConvNode was enough to
11687
make takeTurn() consider the turn to be taken entirely by the
11688
ConvNode; now, the turn is only considered finished if the ConvNode
11689
actually wanted to say something.  This allows ordinary actor-state
11690
background scripts to continue running even when a ConvNode is
11691
active, as long as the ConvNode doesn't generate any NPC conversation
11692
messages.
11693
11694
</div>
11695
11696
<!------------------->
11697
<div class=entry>
11698
11699
The nestedActorAction() function now sets a visual sense context for
11700
the new actor.  (In the past, the nested action incorrectly executed
11701
within the same sense context as the enclosing action, which allowed
11702
actions that shouldn't have been visible to be reported, and vice
11703
versa.)
11704
11705
</div>
11706
11707
<!------------------->
11708
<div class=entry>
11709
11710
If an implied action announcement comes immediately after other
11711
report messages for an action in which the implied action is nested,
11712
the command transcript now automatically inserts a paragraph start
11713
just before the implied action announcement.  It's often desirable to
11714
invoke a nested action in the course of handling a main action, and
11715
in some cases the nested action can trigger implied actions of its
11716
own.  This new transcript feature makes the spacing look better in
11717
these cases when the main action reports its own results before
11718
invoking the nested action.
11719
11720
Similarly, if an implied action announcement occurs after a result
11721
message from a previous implied action, a paragraph break is inserted
11722
before the second implied announcement.  This improves readability
11723
in these cases.
11724
11725
</div>
11726
11727
<!------------------->
11728
<div class=entry>
11729
11730
The CommandTranscript method summarizeAction() now interacts properly
11731
with conversational responses.  A change in 3.0.6m caused a problem
11732
when attempting to summarize a series of conversational messages
11733
(generated by TopicEntry activation); specifically, the summarizer
11734
didn't recognize the new "in-band" conversational boundary markers
11735
that the conversation manager started generating in 3.0.6m.  The
11736
summarizer now handles the conversation markers properly.
11737
11738
</div>
11739
11740
<!------------------->
11741
<div class=entry>
11742
11743
The AgendaItem class has a new property, initiallyActive, that
11744
indicates that an agenda item is active at the start of the game.
11745
During initialization, the library will automatically add each
11746
initially active agenda item to its actor's agenda (by calling
11747
addToAgenda() on the actor).
11748
11749
</div>
11750
11751
<!------------------->
11752
<div class=entry>
11753
11754
The new AgendaItem property agendaOrder makes it easy to control the
11755
priority order of agenda items.  The agenda list is now sorted in
11756
ascending order of the agendaOrder values; this means that the lower
11757
the number, the earlier the item will appear in the agenda list.
11758
Actors choose the first item in the list that's ready to run, so
11759
ready-to-run agenda items will always be executed in order of their
11760
agendaOrder values.  By default, agendaOrder is set to 100; set a
11761
lower value if you want the item to go earlier than other items, a
11762
higher number if you want it to go later.  If you don't care about the
11763
ordering, you can leave the default value unchanged.
11764
11765
<p>Note that readiness is more important than agendaOrder.  Suppose
11766
that AgendaItem A has a lower agendaItem value, and thus goes earlier
11767
in the list, than AgendaItem B.  Despite this list order, if B is
11768
ready to run and A is not, B will be executed.
11769
11770
</div>
11771
11772
<!------------------->
11773
<div class=entry>
11774
11775
The new class SuggestedAskForTopic can be mixed into an AskForTopic
11776
object's superclass list to add the "ask for" to the topic inventory.
11777
This works in parallel with the other SuggestedTopic subclasses.
11778
11779
</div>
11780
11781
<!------------------->
11782
<div class=entry>
11783
11784
In the past, AltTopic didn't work properly with SpecialTopic.  This
11785
has been corrected; you can now create AltTopic children of
11786
SpecialTopic entries, and they'll work as you'd expect.
11787
11788
<p>In a related change, SpecialTopic now inherits from
11789
SuggestedTopicTree, rather than SuggestedTopic as it did in the past.
11790
This ensures that a special topic will be suggested in the topic
11791
inventory when any of its AltTopic children are active.
11792
11793
</div>
11794
11795
<!------------------->
11796
<div class=entry>
11797
11798
The library now defines template variations that allow defining
11799
firstEvents lists with various TopicEntry/ShuffledTextList
11800
combinations: TopicEntry, MiscTopic, SpecialTopic, DefaultTopic,
11801
AltTopic.  Now, if you define an instance of one of these classes,
11802
your definition can include two lists: the first will be the
11803
firstEvents list, and the second will be the eventList list.
11804
11805
</div>
11806
11807
<!------------------->
11808
<div class=entry>
11809
11810
The new DefaultAskForTopic class lets you define a default response
11811
to an ASK FOR command.  This new class is parallel to the other
11812
DefaultTopic subclasses.
11813
11814
</div>
11815
11816
<!------------------->
11817
<div class=entry>
11818
11819
The various DefaultTopic subclasses are now arranged in a hierarchy
11820
of low "match score" values.  In the past, all DefaultTopics used a
11821
match score of 1, which generally made them rank lower than any
11822
non-default topic, but didn't differentiate among different default
11823
topics that matched the same input topic.  Now, the single-type
11824
defaults (DefaultAskTopic, DefaultTellTopic, etc.) have a match score
11825
of 3, the multi-type defaults (DefaultAskTellTopic, etc.) have a
11826
match score of 2, and DefaultAnyTopic has a score of 1.  This means
11827
that a single-type default will take precedence over a multi-type
11828
default, which will in turn take precedence over an ANY default.
11829
This lets you define a DefaultAskTopic that will handle any ASK
11830
command, for example, and a DefaultAnyTopic to handle everything else.
11831
11832
</div>
11833
11834
<!------------------->
11835
<div class=entry>
11836
11837
The initiateTopic() method (in Actor, ActorState, and ConvNode) now
11838
remembers that the player character is talking to the NPC.  This
11839
ensures that commands that check the current interlocutor, such as
11840
TOPICS, properly recognize that the characters are talking to one
11841
another.
11842
11843
</div>
11844
11845
<!------------------->
11846
<div class=entry>
11847
11848
A problem in the library generated a spurious "you're not talking to
11849
anyone" message under certain obscure circumstances involving an
11850
automatic "topic inventory" scheduled at the start of a conversation.
11851
This is now fixed.
11852
11853
</div>
11854
11855
<!------------------->
11856
<div class=entry>
11857
11858
In some cases, if an actor was in a ConvNode but didn't say anything
11859
on a given turn, the actor was incorrectly set as the most recent
11860
pronoun.  The library was being overly aggressive about setting the
11861
pronoun as though the actor had said something, as a convenience to
11862
the player to respond to the actor.  The library no longer sets the
11863
pronoun unless the actor actually says something (i.e., some text is
11864
generated in the course of the actor's turn while in the ConvNode).
11865
11866
</div>
11867
11868
<!------------------->
11869
<div class=entry>
11870
11871
In the English language module, the vocabulary initializer now
11872
ignores extra spaces after delimiters (such as '/' or '*').  This
11873
makes it easier to break up long vocabulary initializers across
11874
multiple lines of code.  For example:
11875
11876
<p><pre>
11877
  + Thing 'big large huge gigantic giant book/tome/volume/
11878
          text/manuscript' 'huge tome'
11879
    // etc
11880
  ;
11881
</pre>
11882
11883
<p>Note the line break in the middle of the list of nouns.  This
11884
introduces an extra space into the string, which is now perfectly
11885
okay.
11886
11887
</div>
11888
11889
<!------------------->
11890
<div class=entry>
11891
11892
In the English parser, the literal adjective wildcard string has been
11893
changed.  In the past, "*" (an asterisk within double quotes) was the
11894
wildcard character.  This made it difficult to match literally an
11895
asterisk in the input, so the wildcard is now the character \u0001
11896
(i.e., Unicode code point 1), which is highly unlikely to be used in
11897
input.
11898
11899
</div>
11900
11901
<!------------------->
11902
<div class=entry>
11903
11904
In the English parser, 'miscVocab' was used as a token property
11905
instead of 'miscWord' in a few places.  The correct token type
11906
should have been 'miscWord'; this has been corrected.
11907
11908
</div>
11909
11910
<!------------------->
11911
<div class=entry>
11912
11913
The menu system now "wraps" up-arrow and down-arrow keys at the top
11914
and bottom of a list of menu items; that is, if the first menu item
11915
is selected and user presses the up-arrow, the selection moves to the
11916
last menu item, and a down-arrow at the last item selects the first
11917
item.
11918
11919
</div>
11920
11921
<!------------------->
11922
<div class=entry>
11923
11924
The library now provides a template for MenuTopicItem, with slots for
11925
the title string, an optional heading string, and the menu contents
11926
list.  
11927
11928
</div>
11929
11930
<!------------------->
11931
<div class=entry>
11932
11933
When a locked door with lockStatusObvious was examined, a message
11934
indicating its status (locked or unlocked) was meant to be displayed,
11935
but wasn't.  This has been corrected.
11936
11937
</div>
11938
11939
<!------------------->
11940
<div class=entry>
11941
11942
A recent change to OOPS processing (in 3.0.6j) introduced a bug:
11943
typing OOPS after a misspelling in a response to an interactive
11944
parser query didn't work.  For example, if your answer to a
11945
disambiguation question ("which book do you mean...") contained a
11946
typo, you couldn't use OOPS to correct that typo.  This now works
11947
properly again.
11948
11949
</div>
11950
11951
<!------------------->
11952
<div class=entry>
11953
11954
Typing AGAIN after a SpecialTopic command didn't work in the past.
11955
This has been corrected.  AGAIN can now be used to repeat a special
11956
topic, as long as the same comamnd is still valid as a special topic;
11957
if the command isn't a valid special topic any longer, the parser
11958
will simply say that the command cannot be repeated.
11959
11960
</div>
11961
11962
<!------------------->
11963
<div class=entry>
11964
11965
The new Thing method expandPronounList() allows an object to
11966
effectively reverse the effects of filterResolveList() when a pronoun
11967
refers to the object in a subsequent command.  The parser calls this
11968
new method on each of the objects in the "raw" binding for a pronoun
11969
(that is, the set of program objects that were resolved in the
11970
previous command that established the antecedent of the pronoun).
11971
11972
<p>The Thing and CollectiveGroup objects use this new method to
11973
ensure that a collective group's filtering is applied consistently
11974
for each command, whether the command uses a full noun phrase or a
11975
pronoun to refer to the groupable objects. 
11976
11977
</div>
11978
11979
<!------------------->
11980
<div class=entry>
11981
11982
When a noun phrase in a player command refers to an object that has
11983
"facets" (as indicated by the object's getFacets() method), and more
11984
than one facet of the object is in scope, the parser will now
11985
automatically choose only one facet of the object.  The parser chooses
11986
the facet that has the best transparency in the actor's sight-like
11987
senses; if the visibilities are equivalent, then the parser chooses
11988
the facet with the best touch transparency; if visibilities and
11989
touchabilities are equivalent, the parser chooses one arbitrarily.
11990
This change ensures that different facets of the same object will
11991
never create ambiguity in the parser, which is important because a set
11992
of facets is always meant to implement what the player sees as a
11993
single game world object.
11994
11995
<p>In a related change, the parser's method of choosing a facet as the
11996
antecedent of a pronoun has changed slightly.  First, the parser now
11997
considers all in-scope facets when an antecedent has facets, even if
11998
the base antecedent object is itself in scope.  Second, the parser
11999
chooses which in-scope facet to use based on the same criteria as
12000
above: visibility, then touchability.  This ensures that when multiple
12001
facets are in scope (because of sense connectors, for example), the
12002
most readily visible <i>and</i> reachable one will be selected.
12003
12004
</div>
12005
12006
<!------------------->
12007
<div class=entry>
12008
12009
The parser now selects a default antecedant for a pronoun whenever
12010
possible, based on the objects in scope.  For example, if you type
12011
LOOK AT HIM, and you haven't established a prior meaning for HIM (by
12012
referring to a male actor with a previous command), <i>or</i> the
12013
prior meaning of HIM is no longer valid (because that actor is no
12014
longer present), then the parser will assume that HIM refers to a
12015
male actor who is present, assuming there's exactly one.  If there
12016
are no in-scope objects matching the gender of the pronoun, or
12017
multiple matching objects are in scope, the parser has no way of
12018
guessing what the pronoun means.  When a pronoun could only refer to
12019
one object, though, the parser will assume that that's the object you
12020
meant.
12021
12022
</div>
12023
12024
<!------------------->
12025
<div class=entry>
12026
12027
In 3.0.6l, the parser started accepting HIM and HER to select a
12028
unique gendered object from a disambiguation query ("which one do you
12029
mean...").  This handling has been improved slightly: the parser now
12030
treats HIM and HER as <i>narrowing</i> the choices, rather than
12031
requiring a unique match.  If more than one of the choices matches
12032
the pronoun, the parser narrows the choices to the ones that match
12033
and asks for disambiguation help again, this time offering the
12034
reduced list of choices.
12035
12036
</div>
12037
12038
<!------------------->
12039
<div class=entry>
12040
12041
A bug in turn timing showed up when an implied command used
12042
replaceAction(); due to the bug, such a command didn't consume a
12043
turn.  This showed up, for example, when a travel command (GO NORTH)
12044
triggered an OPEN DOOR command, which in turn triggered an UNLOCK
12045
DOOR command, which replaced itself via askForIobj() with an UNLOCK
12046
DOOR WITH WHAT? command.  This has now been corrected.
12047
12048
</div>
12049
12050
<!------------------->
12051
<div class=entry>
12052
12053
In the various places where nested actions are created (nestedAction,
12054
nestedActorAction, remapTo, etc), it's now easier to specify literal
12055
and topic objects.  In the past, it was necessary for the caller to
12056
wrap these types of objects in the appropriate internal parser
12057
structures, such as a ResolvedTopic.  This is no longer necessary:
12058
actions that use special wrappers internally will now automatically
12059
create the appropriate wrappers for you.
12060
12061
<p>In practice, this means that you can simply use a string in any
12062
nested action context where a literal is required, and you can use
12063
a simple Thing or Topic object in any context where a topic is
12064
required.  Examples that formerly required special coding, but now
12065
work in the obvious fashion:
12066
12067
<ul>
12068
<li>remapTo(TypeLiteralOn, typewriter, 'hello')
12069
<li>nestedAction(AskFor, bob, goldKey);
12070
</ul>
12071
12072
</div>
12073
12074
<!------------------->
12075
<div class=entry>
12076
12077
A remapTo() object argument can now be a string, when the new verb
12078
accepts a literal in that position.  For example, you can use
12079
remapTo(TypeLiteralOn, typewriter, 'hello') to remap to the command
12080
TYPE "HELLO" ON TYPEWRITER.
12081
12082
</div>
12083
12084
<!------------------->
12085
<div class=entry>
12086
12087
The parser failed to announce a defaulted object under certain obscure
12088
circumstances.  In particular, if a remapTo() on a two-object action
12089
remapped a command, and the source of the remapping was itself chosen
12090
as a defaulted object, the announcement was missing.  The announcement
12091
will now be generated.
12092
12093
</div>
12094
12095
<!------------------->
12096
<div class=entry>
12097
12098
In libMessages, obscuredReadDesc() and dimReadDesc() incorrectly
12099
returned a string rather than displaying a message, resulting in no
12100
message being displayed when reading a Readable under dim or obscured
12101
visual conditions.  This has been corrected; these libMessages methods
12102
now display their messages directly.
12103
12104
</div>
12105
12106
<!------------------->
12107
<div class=entry>
12108
12109
In the default English messages, the various messages indicating that
12110
an actor is in the room and situated in or on a nested room (such as
12111
sitting in a chair, or standing on a platform) have been changed
12112
slightly.  In the past, these said something like "Bob is here,
12113
sitting on the chair."  Now, the essentially pointless "here" part
12114
has been dropped, so the messages read more simply: "Bob is sitting
12115
on the chair."
12116
12117
</div>
12118
12119
<!------------------->
12120
<div class=entry>
12121
12122
The English library message for attempting to take an UntakeableActor
12123
referred to the wrong object (the actor instead of the direct object)
12124
in one of its clauses.  The message has been corrected.
12125
12126
</div>
12127
12128
<!------------------->
12129
<div class=entry>
12130
12131
The English library message listing the newly revealed objects after
12132
opening an Openable now uses specialized phrasing when an NPC performs
12133
the action: "Bob opens the box, revealing..."  The PC version hasn't
12134
changed: "Opening the box reveals..."
12135
12136
</div>
12137
12138
<!------------------->
12139
<div class=entry>
12140
12141
The English library's default message for attempting to ask oneself
12142
for something (ASK ME FOR...) incorrectly referred to the
12143
substitution parameter "{iobj}" (which isn't available with an ASK
12144
FOR command, because the second noun phrase is actually a topic
12145
phrase).  This has been corrected.
12146
12147
</div>
12148
12149
<!------------------->
12150
<div class=entry>
12151
12152
The English version of the INSTRUCTIONS command now automatically
12153
senses the presence of certain optional conversation features and
12154
mentions the corresponding commands only if they're used in the
12155
game.  In particular, the TOPICS command will be mentioned only
12156
if there are SuggestedTopic instances in the game; the existence
12157
of special topics will be mentioned on if there are SpecialTopic
12158
instances; and the TALK TO command will be mentioned only if
12159
there are InConversationState instances.  This reduces the manual
12160
work needed to customize the conversation system instructions;
12161
if your game uses these features, they'll be mentioned, otherwise
12162
they won't.
12163
12164
</div>
12165
12166
<!------------------->
12167
<div class=entry>
12168
12169
A style tag name can now contain digits, as long it starts with an
12170
alphabetic character.  (In the past, style tag names were only
12171
allowed to contain alphabetic characters.  This makes style tag
12172
naming more consistent with the HTML tag naming rules.)
12173
12174
</div>
12175
12176
<!------------------->
12177
<div class=entry>
12178
12179
The new function overrides(obj, base, prop) makes it easy to test
12180
whether or not the given object 'obj' overrides the property 'prop'
12181
that 'obj' inherits from base class 'base'.  This function returns
12182
true if 'obj' derives from 'base' (that is, obj.ofKind(base) returns
12183
true), <b>and</b> 'obj' and 'base' get their definitions of 'prop'
12184
from different places.
12185
12186
<p>In the past, the library tested in a few places to see if a given
12187
property or method was inherited from a given library base class.
12188
This was <i>almost</i> the same test that overrides() performs, but
12189
didn't work properly in cases where a library base class had been
12190
modified by a game or library extension; when 'modify' is used to
12191
extend a class, the defining class for methods defined in the original
12192
(pre-modification) version of the class is the original version, not
12193
the new version created by 'modify', which takes on the original name.
12194
To allow for 'modify' usage, all of the tests the library used to make
12195
along these lines have now been replaced with calls to overrides()
12196
instead.
12197
12198
</div>
12199
12200
<!------------------->
12201
<div class=entry>
12202
12203
The SENSE_CACHE conditional compilation has been removed, so the sense
12204
caching code is now permanently enabled.  This shouldn't affect any
12205
existing code, since I'm not aware of anyone who's wanted to use the
12206
option to disable the sense cache.
12207
12208
<p>(This is simply an internal change to eliminate some unnecessary
12209
extra source code that's been disabled for a long time anyway.  When
12210
the sense-cache mechanism was first introduced, it was made optional,
12211
so that any games that had problems with the caching could turn it
12212
off.  The code has been active by default for a long time now, and I'm
12213
not aware of anyone who has found it necessary or desirable to disable
12214
it, so there no longer seems to be any value in the added complexity
12215
of having both options.  Removing the conditional option simplifies
12216
the source code by removing the effectively dead code for the option
12217
of disabling the sense cache.)
12218
12219
</div>
12220
12221
<!------------------->
12222
<div class=entry>
12223
12224
Due to a bug in the parser, a run-time error occurred in certain cases
12225
when the player entered a two-object command that was missing its
12226
indirect object, and then answered the parser's prompt for the missing
12227
object.  This has been corrected.
12228
12229
</div>
12230
12231
<!------------------->
12232
<div class=entry>
12233
12234
The standard library tokenizer now accepts function pointers and
12235
anonymous function pointers in the fourth slot (the converter
12236
callback) in a token rule.  The function is invoked using the same
12237
arguments that are used when calling a method of 'self' to convert
12238
the token value.
12239
12240
</div>
12241
12242
<!------------------------------- 3.0.6m --------------------------------->
12243
<div class="sepbar"><a name='306m'></a>3.0.6m</div>
12244
<p><b><i>Released November 15, 2003</i></b>
12245
<p>
12246
12247
<div class=firstentry>
12248
12249
<b>Important compatibility-breaking change #1:</b> The 'explicit'
12250
parameter has been removed from Thing.lookAround() and
12251
Actor.lookAround(), as well as from the internal Thing service
12252
methods lookAroundPov(), lookAroundWithin(), and
12253
lookAroundWithinSense().  This extra parameter was an historical
12254
relic that's no longer used, so it's being removed to simplify the
12255
interfaces to these routines.  Game code is likely to call
12256
lookAround() in a few places, and might even override it, so authors
12257
should check their existing game code and remove this parameter from
12258
any calls or overrides.
12259
12260
</div>
12261
12262
<!------------------->
12263
<div class=entry>
12264
12265
<b>Important compatibility-breaking change #2:</b> The AltTopic
12266
mechanism has been changed slightly.  In the past, AltTopics were
12267
nested one within another to form a group of alternatives.  Now,
12268
AltTopics are still nested within their parent TopicEntry, but
12269
they're no longer nested within one another; instead, they're
12270
simply siblings.  So, for old game code like this:
12271
12272
<p><pre>
12273
  <font color=red><b>// OLD WAY!!!</b></font>
12274
  + TopicEntry @lighthouse "It's very tall...";
12275
  ++ AltTopic "Not really..." isActive=(...);
12276
  +++ AltTopic "Well, maybe..." isActive=(...);
12277
  ++++ AltTopic "Okay, it is..." isActive=(...);
12278
</pre>
12279
12280
<p>...you'd now instead write it like this:
12281
12282
<p><pre>
12283
  // the new way
12284
  + TopicEntry @lighthouse "It's very tall...";
12285
  ++ AltTopic "Not really..." isActive=(...);
12286
  ++ AltTopic "Well, maybe..." isActive=(...);
12287
  ++ AltTopic "Okay, it is..." isActive=(...);
12288
</pre>
12289
12290
<p>The only change you need to make is to remove the additional
12291
nesting from the second and subsequent AltTopic in each group - simply
12292
put all of the AltTopics in a group at the same '+' nesting level.
12293
12294
<p>The old nesting scheme had a tendency to get unwieldy whenever a
12295
single topic had more than one or two alternatives.  The new scheme
12296
makes game code a little cleaner when defining large AltTopic lists.
12297
12298
</div>
12299
12300
<!------------------->
12301
<div class=entry>
12302
12303
<b>Possible compatibility-breaking change #3:</b> The getTraveler()
12304
methods, in both Actor and BasicLocation, now have an additional
12305
parameter giving the connector being traversed.  This allows the
12306
routine to take into account both the actor and the connector
12307
involved in the travel, which can be useful in some cases.  
12308
12309
<p>For example, you might want to set up a travel connector that
12310
leads out of a vehicle, in which case you'd want the actor within the
12311
vehicle rather than the vehicle to be the traveler when the connector
12312
is traversed.  In these cases, you'd override the vehicle's
12313
getTraveler() method to check the connector, returning the actor
12314
rather than the vehicle when the outbound connector is the one being
12315
traversed.
12316
12317
<p>In addition, for greater generality, the "actor" argument to
12318
BasicLocation.getTraveler() (and subclass overrides) has been renamed
12319
to indicate that it now takes a <i>traveler</i> rather than merely an
12320
actor.  Vehicle.getTraveler() takes advantage of this: it now
12321
recursively asks its container for the traveler, passing itself
12322
(rather than the traveler within itself) as the proposed traveler.
12323
These changes allows for situations where an actor is inside a
12324
vehicle that's inside another vehicle, for example.
12325
12326
<p>Finally, Vehicle.getTraveler() now makes an additional check
12327
before returning itself as the traveler: if the connector allows the
12328
traveler within the vehicle to pass (as indicated by the connector's
12329
canTravelerPass() method), but the connector doesn't allow the
12330
vehicle itself to pass, then getTraveler() simply returns the
12331
original traveler rather than trying to make the vehicle travel.
12332
This makes it easy to set up an outbound connector from within a
12333
vehicle - simply set up the connector's canTravelerPass() to exclude
12334
the vehicle itself, and a traveler within the vehicle will
12335
automatically leave the vehicle behind on traversing the connector.
12336
12337
</div>
12338
12339
<!------------------->
12340
<div class=entry>
12341
12342
There are a few minor interface changes in the travel mechanism, all
12343
of which should be transparent to existing game code.
12344
12345
<p>The TravelConnector method connectorBack() now takes a <i>Traveler</i>
12346
object rather than an Actor as its first argument.
12347
12348
<p>The TravelConnector method fixedSource() now takes a Traveler instead
12349
of an Actor as its second argument.
12350
12351
<p>The Thing method getTravelConnector() now accepts a nil 'actor'
12352
argument.  When the actor is nil, it means that the caller is
12353
interested in the structure of the map independently of any actor's
12354
present ability to perceive that structure.  This is useful in some
12355
cases, such as auto-mapping, where we want to know what the map is
12356
actually like rather than merely what it looks like to a given actor
12357
at a given time.
12358
12359
<p>The internal handling of the various PushTravel action subclasses
12360
now uses only the 'verify' stage of the action handling for the
12361
indirect object, when there's an indirect object at all.  For
12362
example, PUSH BOX THROUGH DOOR only calls the door's
12363
dobjFor(GoThrough) 'verify' handler, not any of its other handlers.
12364
This change reflects the fact that the action of a push-travel is
12365
always carried out by a nested TravelVia with the special
12366
PushTraveler object, hence the only need we have for the indirect
12367
object handlers at all during the initial PushTravel handling is for
12368
disambiguation via the 'verify' routine.  The old implementation was
12369
problematic when the indirect object remapped decomposed verb, because
12370
it incorrectly remapped the entire action before the proper nested
12371
action could be invoked.  This change corrects the problem, allowing
12372
the PushTravel varieties to work correctly for any combination of
12373
objects.
12374
12375
<p>In the Traveler class, describeDeparture() and describeArrival()
12376
now show their messages in a visual sense context for the traveler, if
12377
the player character isn't involved in the travel.  This ensures that
12378
the travel is properly described (or properly <i>not</i> described) in
12379
situations where the traveler is visible to the player character but
12380
the motivating NPC isn't, or vice versa, such as when an NPC is inside
12381
an opaque vehicle.
12382
12383
</div>
12384
12385
<!------------------->
12386
<div class=entry>
12387
12388
The Fixture and Immovable classes are now based on a new common base
12389
class, NonPortable.  This change is entirely a matter of the
12390
library's internal organization, and is entirely transparent to game
12391
code - Fixture and Immovable behave exactly like they did before.
12392
12393
<p>The new class was introduced for two reasons.  First, it
12394
consolidates the behavior common to all non-portable objects,
12395
eliminating a small amount of redundancy in the former arrangement.
12396
Second, and much more importantly, it roots all of library's
12397
non-portable object classes in a single base class.  This means that
12398
code can reliably test an object for unportability by checking
12399
obj.ofKind(NonPortable).  In the past, it was necessary to write
12400
(obj.ofKind(Immovable) || obj.ofKind(Fixture)); not only is that test
12401
more cumbersome, but its very form is suggestive of the potential for
12402
additional "||" clauses in the future.  The new arrangement
12403
formalizes in the library a single root class for all unportable
12404
objects, ensuring a clean way for the library and library extensions
12405
to add any future specialized unportables without breaking existing
12406
game code.
12407
12408
<p>Note that this change does <b>not</b> break existing game code
12409
that uses the "||" test; other than the new common base class, the
12410
inheritance structure for Fixture and Immovable and their subclasses
12411
has not changed.  Even so, it wouldn't be a bad idea to replace any
12412
"||" tests in your existing code with the simpler ofKind(NonPortable)
12413
test, because this will ensure that your code takes advantage of the
12414
insulation from future changes that the new class affords.
12415
12416
</div>
12417
12418
<!------------------->
12419
<div class=entry>
12420
12421
The Fixture class (and by inheritance, its subclass Component) now
12422
considers an instance to be owned by a given object if the object is
12423
the Fixture's location, or the location is owned by the object.
12424
Since a Fixture/Component is a permanent part of its location,
12425
it usually is appropriate to consider the component to be owned
12426
by anything that owns the location, as well as to consider the
12427
component owned by the location itself.
12428
12429
</div>
12430
12431
<!------------------->
12432
<div class=entry>
12433
12434
The new mix-in class Attachable (in extras.t) makes it easier to
12435
define objects that can be attached to one another, such as a hose
12436
and a faucet, a plug and an electrical outlet, or a rope and a
12437
railing.  Attachable is meant to be combined (using multiple
12438
inheritance) with Thing or a Thing subclass.  The class provides a
12439
number of methods that you can override to control which objects can
12440
be attached to one another, and the special effect of enacting out
12441
those attachments.
12442
12443
<p>The Attachable class provides default handlers for AttachTo,
12444
Detach, DetachFrom, and TakeFrom, but it's relatively easy to define
12445
additional, customized action handlers in terms of these default
12446
actions using the standard 'remapTo' mechanism.  For example, if
12447
you were defining a rope, you could define a TieTo action, and then
12448
map TieTo to AttachTo in your rope object.
12449
12450
<p>The new classes PermanentAttachment and PermanentAttachmentChild
12451
are subclasses of Attachable for cases where you describe objects as
12452
attached in the story text, but you don't want to allow the objects
12453
to be detached from one another.  Describing objects as attached
12454
tends to invite a player to try to detach them; these classes lets
12455
the objects provide customized responses to the player's attempts,
12456
without actually allowing the objects to come apart.  (These classes
12457
aren't intended for mere components; the Component class is adequate
12458
for that.  PermanentAttachment is for situations such as a ball
12459
attached with a string to a paddle, where essentially separate
12460
objects are conspicuously attached to one another.)
12461
12462
</div>
12463
12464
<!------------------->
12465
<div class=entry>
12466
12467
The new mix-in class PresentLater makes it easy to set up objects that
12468
aren't in the game world initially, but will appear later in response
12469
to some event.  For example, you might want to create a hidden door
12470
that isn't part of the game world until the player casts the DETECT
12471
HIDDEN DOORS spell, or you might want to create a pile-of-leaves
12472
object that shows up at the foot of a tree after the player shakes the
12473
tree.
12474
12475
<p>The traditional way of programming these sorts of objects was to
12476
create the object with a 'nil' initial location, then use moveInto()
12477
to move the object into the game upon the triggering event.
12478
PresentLater provides an alternative.  To use PresentLater, you set up
12479
the object in its eventual location, as though it were going to be
12480
there from the start, but you add PresentLater at the start of the
12481
object's superclass list.  During pre-initialization, the library will
12482
remember the object's starting location, and then move the object to
12483
'nil', effectively removing it from the game world.  Later, when you
12484
want to the object to appear, simply call makePresent() on the object,
12485
and it will automatically move to the eventual location that was noted
12486
during start-up.
12487
12488
<p>The advantage of using PresentLater is that you define the object's
12489
eventual location as part of the object itself, as though it were an
12490
ordinary object; this means that you don't have to specify its
12491
eventual location as part of some method (in a moveInto call)
12492
elsewhere in the source code.  Another advantage is that you can use
12493
the makePresentByKey() method to bring a whole set of related objects
12494
into the game world at once: you can give each PresentLater object a
12495
"key" property, which is just an arbitrary value you choose to
12496
identify a group of objects, and then bring all objects that have that
12497
key into the game world at once.
12498
12499
</div>
12500
12501
<!------------------->
12502
<div class=entry>
12503
12504
The new class Unthing represents the <i>absence</i> of an object.  This
12505
class is useful for the occasional situation where a player is likely to
12506
assume that an object is present even though it's not.  For example,
12507
sometimes an object becomes hidden, but a player might not notice that;
12508
rather than letting the regular parser error handle it, we can create
12509
an Unthing that explains that the object can no longer be seen.
12510
Unthing is a simple subclass of Decoration, with a customized default
12511
handling message.
12512
12513
</div>
12514
12515
<!------------------->
12516
<div class=entry>
12517
12518
The travelerDirectlyInRoom precondition object has been replaced with
12519
a new TravelerDirectlyInRoom class.  This change allows the caller to
12520
create the precondition object with the full set of information it
12521
needs via the class's constructor.  This change is probably
12522
transparent to existing game code, as game could would have little
12523
reason to use this precondition.
12524
12525
</div>
12526
12527
<!------------------->
12528
<div class=entry>
12529
12530
The class Thing now defines the method checkTravelerDirectlyInRoom();
12531
the default implementation simply defers to the container.  This
12532
ensures that connectors that are defined inside ordinary objects (for
12533
example, a hole in a bookcase) will properly ensure that a traveler is
12534
in the Thing's containing Room or NestedRoom before travel.  In the
12535
past, the absence of this method meant that there were no conditions
12536
at all on a traveler's initial location in such cases.
12537
12538
</div>
12539
12540
<!------------------->
12541
<div class=entry>
12542
12543
The dropDestinationIsOutRoom precondition now moves the actor,
12544
rather than the traveler (to the extent that they differ), to the
12545
outer room when needed.  (Since the actor is attempting to reach the
12546
outer room in these cases, it makes more sense to move the actor,
12547
rather than any vehicle the actor is inside.)
12548
12549
<p>Similarly, the Floor object's SitOn and LieOn handlers now apply a
12550
precondition requiring the actor, rather than the traveler, to be in
12551
the room directly containing the Floor object.  
12552
12553
</div>
12554
12555
<!------------------->
12556
<div class=entry>
12557
12558
The new VocabObject method getFacets() returns a list of "facets"
12559
of an object.  These are other objects that share the same parsing
12560
identity; for example, the two sides of a door are facets of the
12561
same physical object, from a character's perspective, so each side
12562
would return a list containing the other side from getFacets().
12563
In fact, the Door class overrides getFacets() to do just this.
12564
12565
<p>The parser uses getFacets() to resolve an out-of-scope pronoun
12566
antecedent, if possible.  If the player uses a pronoun, and the
12567
antecedent is out of scope, the parser calls the antecedent's
12568
getFacets() method, and looks for a facet that's in scope; if it
12569
finds an in-scope facet, the parser uses that facet as the
12570
replacement antecedent.  For example, if you type OPEN DOOR, GO
12571
THROUGH IT, THEN CLOSE IT, the parser will now correctly resolve the
12572
second "it" to the door.  In the past, the second "it" wasn't
12573
resolvable, because it referred to the side of the door that's in the
12574
other room and thus out of scope after the travel.  Using the new
12575
facet list capability, the parser can now resolve the second "it"
12576
to the side of the door that is in scope.
12577
12578
<p>(If more than one new facet of the object is in scope in these
12579
cases, the pronoun resolver will take the one that's most readily
12580
visible - that is, the one that has the most "transparent" sense path
12581
in the actor's visual senses.  If all of the in-scope facets are
12582
equally visible, the resolver just picks one arbitrarily.)
12583
12584
<p>By default, VocabObject.getFacets() simply returns an empty list.
12585
The Door and Passage classes override the method to return a list
12586
containing the linked object representing the other side of the door
12587
or passage, if there is one.  The new MultiFaceted object returns the
12588
list of facet objects that it synthesizes; each facet instance of
12589
a MultiFaceted does the same thing.
12590
12591
<p>You can customize getFacets() whenever you use multiple objects
12592
with a shared parser identity.  One common case where you might want
12593
to do this is "object transmutation," where you substitute one object
12594
for another in order to effect a radical change in the setting.  For
12595
example, you might have one object representing a wooden dining
12596
table, and another representing the pile of splintered wood that an
12597
enraged chef turns it into after the guests insult his cooking.  In
12598
this case, you could override getFacets() in the table so that it
12599
returns the pile-of-splintered-wood object.
12600
12601
</div>
12602
12603
<!------------------->
12604
<div class=entry>
12605
12606
The class AutoMultiLoc has been removed, and its capabilities have
12607
been rolled directly into the MultiLoc class itself.  All of the
12608
initialization properties and methods (initialLocationClass,
12609
isInitiallyIn, and buildLocationList) have been moved into MultiLoc,
12610
and they work the same as they used to.  There really wasn't any need
12611
for a separate AutoMultiLoc class, since the two styles of
12612
initialization (enumerated and rule-based) can coexist quite easily in
12613
the single class.
12614
12615
<p>Along the same lines, the DynamicMultiLoc class has been removed,
12616
and its functionality has been rolled into MultiLoc.  In particular,
12617
the reInitializeLocation() method is now part of the base MultiLoc
12618
class.
12619
12620
<p>If you have any AutoMultiLoc or DynamicMultiLoc objects in your
12621
existing game code, you should simply change the AutoMultiLoc or
12622
DynamicMultiLoc superclass to MultiLoc.  The objects should then
12623
behave the same as they did before.
12624
12625
</div>
12626
12627
<!------------------->
12628
<div class=entry>
12629
12630
MultiLoc.moveOutOf() caused a run-time error due to a mismatched
12631
call to notifyRemove().  This is now fixed.
12632
12633
</div>
12634
12635
<!------------------->
12636
<div class=entry>
12637
12638
The new classes MultiInstance and MultiFaceted are useful for cases
12639
where you want to create an object in multiple locations, but
12640
MultiLoc isn't suitable.  A MultiLoc is suitable when a single object
12641
is contained <i>entirely</i> and <i>simultaneously</i> in more than
12642
one location; when a single large object spans several locations, or
12643
when you simply want to duplicate a ubiquitous background object in
12644
several places, the new classes are better.
12645
12646
<p>MultiInstance is good when you want to duplicate a ubiquitous
12647
background object in multiple locations: trees in a forest, the sun
12648
in outdoor locations, crowds in the street.  MultiFaceted is for
12649
large objects that span many locations, such as rivers or long ropes.
12650
MultiLoc isn't ideal for these sorts of cases because the sense
12651
system treats a MultiLoc as a single object that's entirely in all of
12652
its locations at once; this means, for example, that if it's lit in
12653
one place, it's lit everyplace. 
12654
12655
<p>MultiInstance and MultiFaceted work mostly like MultiLoc from the
12656
programming perspective.  Internally, though, rather than appearing
12657
itself in each of its locations, a MultiInstance or MultiFaceted
12658
creates a separate "instance" object for each of its locations.  Each
12659
instance is an ordinary singly-located object, so the library creates
12660
one per location.  The instance objects are instances of a template
12661
that you define as part of the MultiInstance or MultiFaceted object.
12662
12663
<p>The new classes present the MultiLoc multi-location interface, so
12664
you can add and subtract locations as needed, using the usual
12665
routines: moveInto(), moveIntoAdd(), moveOutOf().  You can also set
12666
the initial set of locations as you would for a MultiLoc: you can set
12667
locationList to the list of initial locations, or you can define
12668
initialLocationClass, isInitiallyIn, and/or buildLocationList.
12669
12670
<p>The instances of a MultiInstance or MultiFaceted are all
12671
essentially identical, so these classes are only good for relatively
12672
homogeneous objects.  These classes aren't appropriate for cases
12673
where you want to present distinctive aspects of an object, such as
12674
the different sides of a large building, or distinctive individual
12675
objects, such as different people in a crowd.  When the individual
12676
parts are distinct, you're best off just creating separate objects
12677
for the different instances.  The new classes are mainly for
12678
convenience in cases where you'd otherwise have to repeat an
12679
identical object definition in several locations.
12680
12681
</div>
12682
12683
<!------------------->
12684
<div class=entry>
12685
12686
The new pre-conditions dobjTouchObj and iobjTouchObj can be applied
12687
to the indirect or direct object (respectively) of a two-object
12688
action, to require that the one object can touch the other.  This is
12689
useful for actions where the actor manipulates one of the objects
12690
directly, but manipulates the other object only indirectly using
12691
the first object.  
12692
12693
<p>For example, PUSH COIN WITH STICK would be a good
12694
place to use iobjTouchObj as a direct object precondition: the
12695
actor is manipulating the stick directly, so the actor has to be
12696
able to touch the stick, but the coin only needs to be reachable
12697
indirectly with the stick.  Another example: PLUG CORD INTO OUTLET
12698
requires direct manipulation of the cord, but only the cord needs
12699
to touch the outlet, so this would be a good case for dobjTouchObj
12700
as a precondition on the indirect object.
12701
12702
<p>In the class Thing, the default direct object handlers for the
12703
actions MoveWith, TurnWith, ScrewWith, and UnscrewWith now use the
12704
iobjTouchObj condition rather than touchObj condition.  These verbs
12705
all generally model interactions where the direct object only needs
12706
to be reachable through the indirect object.  The new class Attachable
12707
uses dobjTouchObj as a precondition on the indirect object.
12708
12709
<p>To enable the new iobjTouchObj condition, the TouchObjCondition
12710
class can now handle a yet-unresolved source object during the
12711
verification stage.  When the source object is nil, the pre-condition
12712
simply skips its verification stage.  This allows a TouchObjCondition
12713
to be applied across objects for a two-object action: for example, it
12714
allows you to apply a condition to the direct object that the indirect
12715
object can touch it.
12716
12717
</div>
12718
12719
<!------------------->
12720
<div class=entry>
12721
12722
The new preconditions sameLocationAsIobj and sameLocationAsDobj let
12723
you require that a given object is in the same immediate location as
12724
the other object of a two-object command.  You use sameLocationAsIobj
12725
as a precondition on a direct object, and sameLocationAsDobj as a
12726
precondition on an indirect object.  Both of these condition objects
12727
are based on the class SameLocationCondition, which you can construct
12728
dynamically to require the target object to be in the same location as
12729
an arbitrary second object, which need not be directly involved in the
12730
command.
12731
12732
<p>These conditions use the new Thing method tryMovingObjInto(obj),
12733
which tries to move the given object 'obj' into 'self'.  This method
12734
is customized in Room, Container, Surface, and Actor to generate
12735
appropriate implied commands for those classes, and you can override
12736
it in your own objects as needed.
12737
12738
</div>
12739
12740
<!------------------->
12741
<div class=entry>
12742
12743
The new Actor method endConversation() effectively lets an NPC say
12744
GOODBYE of its own volition, ending a conversation without waiting
12745
for the player to leave or say GOODBYE.  This is the complement of
12746
Actor.initiateConversation: it lets an NPC initiate the end of a
12747
conversation.
12748
12749
<p>The new conversation-ending code endConvActor indicates that we're
12750
ending the conversation of the actor's volition.
12751
12752
</div>
12753
12754
<!------------------->
12755
<div class=entry>
12756
12757
The new ConvNode method noteLeaving() is called when the conversation
12758
node is about to become inactive.  This is the complement of
12759
noteActive().  This method doesn't do anything by default, but
12760
instances can use it to trigger side effects when leaving the node.
12761
12762
</div>
12763
12764
<!------------------->
12765
<div class=entry>
12766
12767
The conversation manager's mechanism that keeps track of conversation
12768
responses has been changed to make it better able to handle multiple
12769
conversations on a single turn.  In particular, the conversation manager
12770
now flags the start and end of each response text in the text stream.
12771
Because the "transcript" subsystem captures displayed text
12772
and defers its actual output until later, difficult synchronization
12773
problems arose if a game tried to trigger multiple responses from
12774
different actors on a single turn.  This change should be transparent
12775
to existing game code.
12776
12777
</div>
12778
12779
<!------------------->
12780
<div class=entry>
12781
12782
TopicEntry has a new method, setTopicPronoun(), that tries to set a
12783
pronoun antecedent when the topic is matched.  The default
12784
handleTopic() method automatically calls the new method.
12785
12786
<p>It's not always possible for setTopicPronoun() to guess about an
12787
antecedent for a topic phrase match, because TopicEntry instances can
12788
match more than one game object, and topic phrases by their nature can
12789
refer to more objects than are present visually.  The new method will
12790
set a pronoun antecedent for the topic if the topic phrase in the
12791
player's input yields one object when "intersected" with the
12792
TopicEntry's 'matchObj' list.  The method first looks only at in-scope
12793
objects, then looks to the "likely" list, but only if there are no
12794
in-scope matches.  If the intersection yields more than one object,
12795
the library doesn't set a pronoun antecedent at all, since the match
12796
is ambiguous.
12797
12798
<p>Since this heuristic procedure can't always decide on an
12799
antecedent, you might occasionally want to set the antecedent
12800
explicitly in a particular TopicEntry.  You can do this by overriding
12801
the TopicEntry instance's setTopicPronoun(fromActor,topic), in which
12802
you'd call fromActor.setPronounObj(obj), where 'obj' is the game
12803
object you want to set as the antecedent.
12804
12805
</div>
12806
12807
<!------------------->
12808
<div class=entry>
12809
12810
In the past, when an "again" command was used to repeat a command
12811
directed to a non-player character ("bob, go east"), the turn counter
12812
incorrectly advanced by two turns.  This was due to an error in the
12813
mechanism that allows one actor to wait for another to finish a
12814
command.  This is now fixed.
12815
12816
<p>A separate problem prevented an undo savepoint from being created
12817
for an "again" command repeated a command directed to another
12818
character.  Since no savepoint was created, typing "undo" after such
12819
an "again" command took back not only the "again" turn but the turn
12820
before it as well.  The savepoint is now created properly.
12821
12822
</div>
12823
12824
<!------------------->
12825
<div class=entry>
12826
12827
Due to a bug, the conversation mechanism didn't enter a conversation
12828
(i.e., didn't show the "greeting protocol") if a DefaultTopicEntry was
12829
used for a response.  This has been fixed.
12830
12831
<p>As part of this change, the ActorTopicEntry class, which was
12832
introduced in the refactoring of the TopicEntry class introduced in
12833
3.0.6l, has been eliminated.  On further consideration, the
12834
bifurcation of TopicEntry into actor-associated and
12835
non-actor-associated subtypes wasn't very clean, since it implied a
12836
similar split for some of the other classes that work with TopicEntry,
12837
notably AltTopic and DefaultTopic.  This was too unwieldy.
12838
12839
<p>So, ActorTopicEntry has been removed.  In its place, the "topic
12840
owner" abstraction, which was introduced in 3.0.6l, has been used
12841
throughout the base TopicEntry class to replace the need for an
12842
associated actor.  This means that the base TopicEntry can do
12843
everything that it did before (and everything that ActorTopicEntry did
12844
before), but without any assumption that there's an associated actor.
12845
The getActor() method is still present, but it's now strictly for the
12846
convenience of game code; the library no longer assumes that topic
12847
entries to be associated with actors.  The TopicEntry.getActor()
12848
method simply returns the topic owner if it's of class Actor,
12849
otherwise nil.
12850
12851
<p>These changes should have no impact on existing game code, since
12852
the ActorTopicEntry was intended as an internal class structure only.
12853
12854
</div>
12855
12856
<!------------------->
12857
<div class=entry>
12858
12859
A bug in the TopicResolver class caused a run-time error for
12860
a command like ASK <i>someone</i> ABOUT ALL.  This is now fixed.
12861
12862
</div>
12863
12864
<!------------------->
12865
<div class=entry>
12866
12867
When the ConsultAbout action picks a default consultable object based
12868
on the actor's last ConsultAbout command, the action now marks the
12869
defaulted object as such, which triggers the usual announcement of
12870
the default object.
12871
12872
</div>
12873
12874
<!------------------->
12875
<div class=entry>
12876
12877
The typographicalOutputFilter object (in en_us.t) is now a little
12878
smarter about what it considers sentence-ending punctuation.  If a
12879
lower-case letter or a hyphen of some kind follows what the filter
12880
would otherwise take for sentence-ending punctuation, it doesn't treat
12881
it as a sentence ending.  This gives better results in the common case
12882
of an exclamation point or question mark within a quoted passage:
12883
"'Who are you?' he asked."  It also helps in some less common
12884
cases, such as when an exclamation point is embedded in a sentence,
12885
such as in an interjection set off by dashes ("And then -- oh no! --
12886
I dropped it").
12887
12888
</div>
12889
12890
<!------------------->
12891
<div class=entry>
12892
12893
The PendingCommandInfo class has been refactored into a couple of
12894
subclasses for a cleaner class structure.  PendingCommandInfo is now
12895
an abstract base class; the new concrete subclasses
12896
PendingCommandToks, PendingCommandAction, and PendingCommandMarker now
12897
implement the specialized behavior that was formerly embedded in the
12898
single class and handled conditionally.  These classes are mostly for
12899
internal use in the library, so this should have no impact on any
12900
existing game code.
12901
12902
</div>
12903
12904
<!------------------->
12905
<div class=entry>
12906
12907
Some messages in BasicContainer have been modified slightly to remove
12908
the assumption from the base class that it's an object that can be
12909
opened.  First, the new properties cannotTouchThroughMsg and
12910
cannotMoveThroughMsg give property pointers, referring to
12911
playerActionMessages properties, that specify the messages to use
12912
when an object cannot be reached or moved through the container's
12913
containment boundary.  By default, these now refer to the new messages
12914
cannotTouchThroughContainer and cannotMoveThroughContainer, which don't
12915
say anything about the container being closed.  Second, BasicOpenable
12916
class overrides these two new properties to refer to the original
12917
cannotTouchThroughClosed and cannotMoveThroughClosed messages.
12918
Third, the tryImplicitRemoveObstructor() method that was formerly
12919
in BasicContainer has been moved to BasicOpenable instead, eliminating
12920
the assumption in BasicContainer that the obstruction can be removed
12921
by opening the container.
12922
12923
<p>Note that these changes are designed in such a way that objects
12924
based on both Openable and Container (either by mixing the two
12925
superclasses, or by using the library class OpenableContainer) should
12926
be unaffected.  Objects based on Container or BasicContainer, without
12927
any Openable mix-in, should now behave more logically, in that they
12928
won't assume anything about being openable.
12929
12930
</div>
12931
12932
<!------------------->
12933
<div class=entry>
12934
12935
The touchObj precondition incorrectly reported two failure messages
12936
if an implied command failed trying to remove an obstruction to touch.
12937
The failure message of the implied command itself was shown, and a
12938
separate failure message explaining that the target object isn't
12939
reachable was also shown; in such cases, only the implied command
12940
failure should have been reported.  The precondition now omits the
12941
redundant second message.
12942
12943
</div>
12944
12945
<!------------------->
12946
<div class=entry>
12947
12948
KeyedLockable is now more flexible about the "known key list" and who
12949
owns it.  In the past, the "master object" of a linked lockable (the
12950
master object of a two-sided door, for example) always owned the known
12951
key list; this made it impossible to have separate keys operate the
12952
two sides of a door, and also created a dependency on which side of
12953
the door was the master.  Now, KeyedLockable instead uses the local
12954
side's known key list if it has one, and only uses the master side's
12955
list if either the local side has an empty list or the master side has
12956
no list; only if the local side has an empty list, and the master side
12957
has a list, is the master side used.  This makes initialization of
12958
two-sided doors much more flexible, because it no longer matters which
12959
side is the master for the purposes of the known key list.
12960
12961
</div>
12962
12963
<!------------------->
12964
<div class=entry>
12965
12966
In 3.0.6j, we introduced the notion of whether or not the status of a
12967
Lockable is known.  The idea was that actors shouldn't just
12968
automatically unlock a door on trying to open it unless they have
12969
some reason to know the door is locked in the first place.
12970
Unfortunately, this mechanism took away the important playability
12971
convenience feature that automatically unlocks locked doors when it's
12972
obvious how to do so.
12973
12974
<p>This mechanism is now replaced with something a little more
12975
subtle, which solves the same problem without any loss of convenience
12976
for the player.  Instead of letting the original OPEN command fail on
12977
encountering a door that's locked but not previously known to be
12978
locked, the library now inserts a "testing" action into the sequence
12979
ahead of the implied UNLOCK.  The "testing" action represents the
12980
actor's first attempt to open the lockable, as in attempting to turn
12981
a locked doorknob.  This first phase fails, but instead of letting
12982
the rest of the command fail, we consider the actor to have
12983
<b>immediately</b> learned from the first phase that the object is
12984
locked, so we proceed directly to an implied UNLOCK action.  The
12985
result looks like this:
12986
12987
<p><pre>
12988
&gt;go north
12989
(first trying the door and finding it locked, unlocking it, then 
12990
opening it)
12991
</pre>
12992
12993
<p>Note that the lockStatusObvious property of the former scheme
12994
still applies.  If lockStatusObvious is true, then the extra
12995
"testing" phase is omitted, since we can tell just looking at the
12996
object that it's locked.  Note also that the "testing" phase is
12997
only used when the object is actually locked; when it's not locked,
12998
the OPEN command succeeds, so there's no need to split the OPEN
12999
action into the two phases.
13000
13001
</div>
13002
13003
<!------------------->
13004
<div class=entry>
13005
13006
The Door class now uses a custom cannotTravel() message, rather than
13007
using the default message for the location.  The message explains that
13008
the travel is not possible because the door is closed; the generic
13009
cannot-travel message for a room simply claims that the travel is
13010
impossible, which isn't as specific as we can be about it.
13011
13012
</div>
13013
13014
<!------------------->
13015
<div class=entry>
13016
13017
The Openable class has a new method, openStatus, that makes it easier
13018
to override the open/closed status addendum that's shown as part of
13019
the object's description.  The openableContentsLister now calls this
13020
method to show the status; the default implementation just says "it's
13021
open" (or equivalent, adjusted for gender and number).  An Openable
13022
can override this to customize the message as needed.
13023
13024
</div>
13025
13026
<!------------------->
13027
<div class=entry>
13028
13029
The Passage class's initialization of a two-sided relationship has
13030
been refined slightly.  In the past, the non-master side of a
13031
two-sided passage explicitly set its master object's otherSide
13032
property to point to the non-master side.  Now, instead of setting
13033
the property directly, the non-master side calls the master object's
13034
initMasterObject() method with the non-master side as the parameter;
13035
by default, initMasterObject() simply sets 'otherSide' to the other
13036
object.  This makes it easier to customize the initialization for
13037
cases where more than two objects are involved in a passage
13038
relationship, or where the passage relationship is dynamic, by
13039
allowing the master object to directly control its own initialization.
13040
13041
</div>
13042
13043
<!------------------->
13044
<div class=entry>
13045
13046
In the Candle class, when the object runs out of fuel, it now displays
13047
its "burned out" message <i>before</i> actually cutting off its light
13048
source (by marking itself as unlit).  In the past, the order of these
13049
operations was reversed, which caused the library to suppress the
13050
"burned out" message when the candle was the only light source.  The
13051
message was suppressed because these operations are performed in a
13052
daemon that runs in the "sight" sense context of the candle itself;
13053
once the candle is marked as unlit, it becomes invisible when there's
13054
no other light source, and so any message displayed in its sight
13055
context is suppressed.  By showing the message while the candle is
13056
still marked as lit, we ensure that the message will be seen as long
13057
as the candle is in view of the player character.
13058
13059
</div>
13060
13061
<!------------------->
13062
<div class=entry>
13063
13064
The Readable class now generates its "obscured" and "dim" default
13065
descriptions properly.  A bug formerly caused a run-time error when
13066
attempting to read a Readable under these sense conditions.
13067
13068
</div>
13069
13070
<!------------------->
13071
<div class=entry>
13072
13073
The menu system now includes an automatic sorting mechanism,
13074
which sorts a menu's entries into a game-defined order each time the
13075
menu is displayed.  The default initializeContents() method in the
13076
MenuObject class does the sorting, based on the new 'menuOrder'
13077
properties of the items in the menu.  The 'menuOrder' property is
13078
an integer value giving the relative order of an item among its
13079
siblings.  By default, 'menuOrder' returns the 'sourceTextOrder'
13080
value for the menu item, so the default ordering is simply the
13081
original ordering of the items in the source file.
13082
13083
</div>
13084
13085
<!------------------->
13086
<div class=entry>
13087
13088
In the English module, the new property isQualifiedName generalizes
13089
the function of the existing isProperName property.  isProperName
13090
indicates that a 'name' property is "proper," meaning it's the name
13091
of a person or place - the kind of noun that's usually capitalized in
13092
English.  Proper names don't require "qualification" when they appear
13093
in sentences, which basically means that they don't need articles
13094
like "the" or "a", because they're inherently definite.  The new
13095
isQualifiedName property can be set to true for an object when the
13096
name is fully qualified, but isn't proper.  By default, a proper name
13097
is considered qualified, but the two properties can be set
13098
independently as needed.
13099
13100
<p>An example of a non-proper but qualified name is "your book."
13101
This isn't the proper name of the book, but the possessive pronoun
13102
makes it fully qualified, making it incorrect to add an article when
13103
using the name in a sentence.
13104
13105
<p>In practice, at the moment, "qualified" and "definite" have the
13106
same effect, which is to omit any articles when the name is used in a
13107
sentence.  The new property is intended to separate the two concepts
13108
in case there's a need to distinguish them in the game or in future
13109
library changes.
13110
13111
</div>
13112
13113
<!------------------->
13114
<div class=entry>
13115
13116
The English parser has a new bit of fine-tuning in its verb phrase
13117
chooser for a particular type of ambiguous phrasing.  In certain
13118
sentences in English, a preposition can be interpreted either as part
13119
of a noun phrase or as a structural part of the verb; for example,
13120
DETACH STRING FROM BOX could be interpreted either as a verb with two
13121
objects (STRING as the direct object, BOX as the indirect object), or
13122
as a verb with a single object (STRING FROM BOX as the direct
13123
object).  English speakers will almost always assume the two-object
13124
interpretation automatically in cases like this; English is such a
13125
strongly positional language that the verb phrase structure tends to
13126
dominate everything else in a sentence.  In the past, the parser
13127
didn't care one way or the other, so when both interpretations were
13128
valid, the parser sometimes arbitrarily chose the much less probable
13129
single-object version.  The parser now takes the verb structure
13130
dominance into account by preferring the intepretation with more
13131
"noun slots" in the verb phrase, whenever there's ambiguity.
13132
13133
</div>
13134
13135
<!------------------->
13136
<div class=entry>
13137
13138
The English parser's tokenizer now treats ampersands essentially as
13139
though they were alphabetic characters for the various kinds of
13140
"word" tokens.  Ampersands have no other meaning to the standard
13141
parser, and show up every so often in names of things, so it makes
13142
sense for the parser to accept them as parts of words.  
13143
13144
<p>Note that an ampersand is treated as alphabetic, not as a
13145
punctuation mark.  This has two implications that might be
13146
counterintuitive, at least to the extent that ampersands look to most
13147
people like punctuation marks.  (In fact, they're not punctuation
13148
marks at all; they're actually ligatures of "et," Latin for "and,"
13149
although the glyph has become so stylized in modern typefaces that
13150
it's hard to see that unless you know what to look for.)  First, an
13151
ampersand is <b>not</b> a token separator, so a sequence like
13152
"T&amp;V" will be read as a single token.  Second, when an ampersand
13153
is surrounded by whitespace (or other token separators), so that it
13154
does count as a separate token, it'll be parsed as a "word" token,
13155
not as punctuation.  For example, "Bob &amp; Sons" is read as three
13156
"word" tokens.  This means that you can use a lone "&amp;" as an
13157
adjective or noun in defining an object's vocabulary.
13158
13159
</div>
13160
13161
<!------------------->
13162
<div class=entry>
13163
13164
In the English module, Thing.conjugateRegularVerb() incorrectly
13165
applied an "-ies" ending to verbs ending in a consonant plus a "y",
13166
such as "say".  This affected routines like itVerb() and nameVerb().
13167
The routine now uses a regular "-s" ending when a vowel precedes
13168
a terminal "y".
13169
13170
</div>
13171
13172
<!------------------->
13173
<div class=entry>
13174
13175
The parser now allows possessive pronoun adjectives ("her book") to
13176
refer back to the previous noun phrase in the same action.  For
13177
example, ASK BOB ABOUT HIS HAT will treat "his" as referring to Bob.
13178
This is accomplished by first trying to find an earlier noun phrase
13179
in the same action that matches the pronoun in number and gender.  If
13180
we find a match, we use it, otherwise we use the ordinary pronoun
13181
antecedent from a previous command.  Note that the number/gender
13182
match ensures that we don't get overzealous in applying this: if we
13183
type ASK BOB ABOUT HER BOOK, we find that BOB doesn't match HER, so
13184
we look to the meaning of HER from a previous command.
13185
13186
<p>As part of this change, the Action routine that was formerly
13187
called getReflexiveBinding has been renamed to getAnaphoricBinding.
13188
The new name better reflects the more generalized function, since it
13189
can be used for other kinds of anaphoric bindings besides reflexives.
13190
This is an internal method that is highly unlikely to be
13191
used in any game code, so this change should be transparent.
13192
13193
<p>("Anaphor" is the linguistic term for any sort of reference to an
13194
earlier noun phrase in a sentence; a reflexive is a particular kind
13195
of anaphor that re-uses a noun phrase from an earlier "slot" in a
13196
predicate to fill another slot in the same predicate, such as HIMSELF
13197
in ASK BOB ABOUT HIMSELF.  The reason reflexives exist in English and
13198
other languages is that they're unambiguously anaphoric: in ASK BOB
13199
ABOUT HIMSELF, HIMSELF can only refer to Bob, whereas the HIM in ASK
13200
BOB ABOUT HIM almost certainly refers to someone other than Bob from
13201
a previous sentence or clause.  The name change in the method
13202
reflects the fact that there are other kinds of anaphoric constructs
13203
besides reflexives; in ASK BOB ABOUT HIS BOOK, the HIS refers
13204
anaphorically to BOB, but it's not reflexive.)
13205
13206
13207
</div>
13208
13209
<!------------------->
13210
<div class=entry>
13211
13212
In Actor.executeActorTurn(), when a pending response is delivered,
13213
the actor now clears its memory of the pending response.  (In the
13214
past, the pending response wasn't cleared, so an NPC with a pending
13215
response would keep delivering the pending response over and over.)
13216
13217
</div>
13218
13219
<!------------------->
13220
<div class=entry>
13221
13222
When AskFor changed to a TopicTAction in 3.0.6l, the Actor handler for
13223
GiveTo was affected but wasn't updated properly.  The GiveTo handler
13224
changes a GiveTo command directed to another actor into an AskFor
13225
command (BOB, GIVE ME THE CROWBAR becomes ASK BOB FOR CROWBAR), so the
13226
AskFor change required this rephrasing to be cast in the new
13227
TopicTAction terms.  This change wasn't made, so the GiveTo handler
13228
didn't work properly.  This has now been fixed.
13229
13230
</div>
13231
13232
<!------------------->
13233
<div class=entry>
13234
13235
Actor.desc no longer shows the postureDesc as part of the description
13236
of an NPC.  Instead, this is shown in examineStatus().  This change
13237
shouldn't affect any existing code; it merely moves around where the
13238
calls are made, but still makes all the same calls in the same
13239
sequence.  The change makes it easier to override an Actor's 'desc'
13240
without changing the overall display format.
13241
13242
</div>
13243
13244
<!------------------->
13245
<div class=entry>
13246
13247
A bug in the sense system prevented a self-illuminating object (an
13248
object with a brightness of 1) from applying its self-illumination to
13249
its own interior surface; the illumination was considered external
13250
only.  This was inconsistent with the normal sense-transmission
13251
rules, and it's now been corrected.  A self-illuminating object is
13252
now considered to have an ambience level of 1 on both its inner and
13253
outer surface.
13254
13255
</div>
13256
13257
<!------------------->
13258
<div class=entry>
13259
13260
A subtle bug in the sense system caused ambient sense energy levels
13261
to be transmitted incorrectly into the interior of objects with
13262
non-transparent fill media.  In particular, the sense system
13263
incorrectly applied the fill medium to the ambience level at the
13264
inner surface of an object as transmitted from the outside of the
13265
object.  This was incorrect because it meant that a viewer on the
13266
inside of an object saw the ambient level to the object adjusted
13267
<i>twice</i> for the fill medium: once for the incorrect adjustment
13268
at the inner surface, and once more for the path from the viewer,
13269
through the fill medium, to the inner surface.  This has been
13270
corrected: the ambient level arriving at the inner surface of an
13271
object from outside the object is now calculated without any
13272
adjustment for the fill medium, and any further transmission inward
13273
is then adjusted for the fill medium.
13274
13275
<p>This problem showed up by making an object invisible from its own
13276
interior when the object had a non-transparent fill medium, and the
13277
light coming in from outside wasn't bright enough to penetrate the
13278
fill medium twice.  For example, a transparent booth filled with
13279
attenuating fog, with external normal illumination (brightness 3),
13280
was not visible from its interior because of the double traversal
13281
of the fog.  Such a booth is now visible from its interior.
13282
13283
</div>
13284
13285
<!------------------->
13286
<div class=entry>
13287
13288
When looking for an object's default associated Noise or Odor, the
13289
Thing methods getNoise() and getOdor() now only consider objects with
13290
an active "presence" in their sense.  That is, getNoise() will only
13291
return a Noise object with a non-nil soundPresence property value,
13292
and getOdor() will only return an Odor with a non-nil smellPresence.
13293
This makes it easier to turn an object's associated sense data on and
13294
off, since you can simply use the presence properties of the Noise
13295
and Odor objects.
13296
13297
</div>
13298
13299
<!------------------->
13300
<div class=entry>
13301
13302
In 3.0.6j, CollectiveGroup stopped matching singular phrases and
13303
phrases with quantities specified (as in "five coins").  This behavior
13304
hasn't changed, but it's now easier to control, with the new method
13305
isCollectiveQuant().  This method returns true if the given "required
13306
quantity" allows using the collective, nil if not.  By default, this
13307
returns true if and only if there's no specific quantity needed (in
13308
which case the quantity parameter is nil).
13309
13310
</div>
13311
13312
<!------------------->
13313
<div class=entry>
13314
13315
RandomTextList and ShuffledTextList can now handle arbitrary event
13316
entries in their lists, using the same rules as the base EventList
13317
class.  (In the past, only strings and nil values were allowed in
13318
these specialized subclasses, but they now use the base class handling
13319
to carry out each event, so they can now handle any sort of event the
13320
base class can.)
13321
13322
</div>
13323
13324
<!------------------------------- 3.0.6l --------------------------------->
13325
<div class="sepbar"><a name='306l'></a>3.0.6l</div>
13326
<p><b><i>Released October 4, 2003</i></b>
13327
<p>
13328
13329
<div class=firstentry>
13330
13331
The actor knowledge and "sight memory" systems have been revamped to
13332
make it easier to keep track of individual knowledge for different
13333
actors.  <b>A few key interfaces have changed, so existing games will
13334
have to make corresponding changes.</b>
13335
13336
<p>First, the main interface changes:
13337
13338
<ul>
13339
<li>obj.seenBy(actor) is now actor.hasSeen(obj)
13340
<li>obj.setSeenBy(actor, stat) is now actor.setHasSeen(obj)
13341
<li>obj.isKnownBy(actor) is now actor.knowsAbout(obj)
13342
<li>obj.setKnownBy(actor, stat) is now actor.setKnowsAbout(obj)
13343
</ul>
13344
13345
<p>Note that the "stat" parameter has been removed from the two "set"
13346
methods.  This parameter was essentially superfluous, since it's rare
13347
to the point of non-existence for a game to want to mark something as
13348
un-seen or unknown after it's been previously seen or known; the new
13349
methods elide this parameter and act like the old methods acted with
13350
the parameter set to true.
13351
13352
<p>You have a choice of how to update your existing game code to the
13353
new interfaces.  The first option is to do the search-and-replace
13354
operations in the list above throughout your game's source code; this
13355
is the recommended option, because it'll make your code consistent
13356
with future documentation.  The second option is to modify the
13357
VocabObject class to reinstate the old methods, defining them in
13358
terms of the new ones:
13359
13360
<p><pre>
13361
modify VocabObject
13362
  seenBy(actor) { return actor.hasSeen(self); }
13363
  setSeenBy(actor, flag) { actor.setHasSeen(self); }
13364
  isKnownBy(actor) { return actor.knowsAbout(self); }
13365
  setKnownBy(actor, flag) { actor.setKnowsAbout(self); }
13366
;
13367
</pre>
13368
13369
<p>Second, how do the changes facilitate separate NPC knowledge
13370
tracking?  The change here is that the Thing and Topic 'seen' and
13371
'isKnown' properties that underlay the old system are still used, but
13372
are now only <i>defaults</i> for tracking the seen/known information.
13373
The actual properties used to track the information are determined on
13374
an actor-by-actor basis, using the new Actor.seenProp and
13375
Actor.knownProp properties.  
13376
13377
<p>By default, Actor defines seenProp as &amp;seen, and knownProp as
13378
&amp;isKnown.  This means that, by default, there's only one
13379
"global" set of knowledge.  To track an NPC's knowledge individually,
13380
simply set seenProp and/or knownProp to new properties unique to that
13381
actor.  For example:
13382
13383
<p><pre>
13384
bob: Person
13385
  // ... other definitions...
13386
  seenProp = &amp;bobSeen
13387
  knownProp = &amp;bobKnown
13388
;
13389
</pre>
13390
13391
<p>This specifies that 'bob' will individually track its knowledge,
13392
separately from any other actors.  When you call bob.setKnowsAbout(obj),
13393
the library will examine obj.bobKnown and obj.bobSeen, because those are
13394
the properties that track bob's knowledge.  Note that this individual
13395
tracking is completely automatic once you define seenProp and knownProp,
13396
since the Actor methods hasSeen, setHasSeen, knowsAbout, and setKnowsAbout
13397
all use seenProp and/or knownProp to do their work.
13398
13399
<p>Note that because the default values in Actor for seenProp and
13400
knownProp are (respectively) &amp;seen and &amp;isKnown, everything
13401
works roughly the same way it did before if you don't override these
13402
properties.  In particular, if you don't care about tracking
13403
individual NPC knowledge, which typical games probably won't, you
13404
only have to worry about 'seen' and 'isKnown' as before.  So, if you
13405
want to initialize an object as pre-known, before the start of the
13406
game, simply set isKnown=true for that object as in the past.
13407
13408
<p>Third, a minor enhancement: the GIVE and SHOW iobjFor() handlers
13409
in Actor now automatically mark the object being shown, and its
13410
visible contents, as having been seen by the actor being shown the
13411
object.  For games that track NPC knowledge separately, this will
13412
ensure that the target of a GIVE or SHOW takes note of having seen
13413
the object in question.
13414
13415
</div>
13416
13417
<!------------------->
13418
<div class=entry>
13419
13420
A new class, Consultable, can be used to implement things like books
13421
and file cabinets: inanimate objects in which an actor can look up a
13422
topic, to find some information.  This class works almost exactly
13423
like the Actor conversation system.  Another new class, ConsultTopic,
13424
serves as the TopicEntry subclass for Consultables.  Simply create
13425
one or more ConsultTopic objects, and locate them within the
13426
Consultable, to populate the consultable object's database of
13427
responses.
13428
13429
<p>In support of the new Consultable class, the TopicDatabase and
13430
TopicEntry classes have been refactored a bit.  In particular, these
13431
two classes no longer assume that they're associated with an actor,
13432
and no longer assume that they're involved in conversation.  The
13433
parts of the former implementations that made assumptions about actor
13434
or conversation associations have been moved into a pair of new
13435
subclasses, ActorTopicDatabase and ActorTopicEntry.  The existing
13436
classes that were based directly on TopicDatabase and TopicEntry are
13437
now based on the new ActorXxx subclasses instead.  For almost all
13438
existing game code, this change should be entirely transparent,
13439
because the final subclasses that most games use still have the same
13440
names and work the same way they did before; the only changes are
13441
some internal reshuffling to abstract out most of the functionality
13442
into the new base classes.
13443
13444
<p>In addition, the TopicResolver class has a new subclass,
13445
ConvTopicResolver, that's used for the conversational actions (ASK
13446
ABOUT, TELL ABOUT).  The base TopicResolver doesn't differentiate
13447
at all among topics; it simply considers everything to be an
13448
equally good match.  The ConvTopicResolver differentiates topics
13449
into three sublists, as it did in the past: objects that are in
13450
physical scope or are known to the actor performing the command;
13451
objects that are "likely" topics, as indicated by the performing
13452
actor's isLikelyTopic(); and everything else.
13453
13454
</div>
13455
13456
<!------------------->
13457
<div class=entry>
13458
13459
The ConsultAbout action in the English module now adds grammar for
13460
some incomplete forms, such as "look up (topic)".  If the player
13461
enters one of these incomplete forms, the parser will prompt for
13462
the missing object in the usual fashion.
13463
13464
<p>Similarly, when the direct object is missing from a CONSULT ABOUT
13465
command, the default is the last object consulted by the same actor,
13466
as long as that object is still visible.  The new Actor property
13467
lastConsulted keeps track of the last object consulted; the new Actor
13468
method noteConsultation() sets this property.  The Consultable class
13469
calls gActor.noteConsultation(self) in its ConsultAbout action()
13470
handler.  This saves the player some typing, since they can leave out
13471
the object to be consulted when they're looking up a series of topics
13472
in the same consultable (they can type simply LOOK UP BOB, for
13473
example).
13474
13475
</div>
13476
13477
<!------------------->
13478
<div class=entry>
13479
13480
The TopicEntry scoring system now uses nil to represent a non-match.
13481
This means the valid scoring range now includes zero and negative
13482
values, which in turn means that it's no longer a problem if
13483
matchScoreAdjustment values reducing scores to zero or below.  This
13484
makes it easier to use score adjustments, since there's no longer any
13485
need to worry about interactions between score values and adjustment
13486
values taking a final score out of range.
13487
13488
</div>
13489
13490
<!------------------->
13491
<div class=entry>
13492
13493
The AskFor action is now a TopicTAction instead of a TIAction.  That
13494
is, the indirect object is now a topic rather than an ordinary
13495
resolved object.  The TIAction implementation was never really
13496
appropriate, since ASK FOR conceptually needs topic-oriented rules
13497
for the indirect object: one needs to be able to ask for things that
13498
aren't in scope, as well as for abstract topics (ASK FOR HELP, ASK
13499
FOR DIRECTIONS).
13500
13501
<p>This change should have little or no impact on existing games.
13502
13503
</div>
13504
13505
<!------------------->
13506
<div class=entry>
13507
13508
The new TopicEntry subclass AskAboutForTopic can be used to make a
13509
single topic entry respond to either ASK ABOUT or ASK FOR for a given
13510
game object or objects (read the name as "ask about/for topic").
13511
Similarly, AskTellAboutForTopic can respond to ASK ABOUT, TELL ABOUT,
13512
or ASK FOR (read the name as "ask/tell about/for topic," although the
13513
TELL FOR combination implied in that reading doesn't make any sense,
13514
obviously).
13515
13516
</div>
13517
13518
<!------------------->
13519
<div class=entry>
13520
13521
The limitSuggestions property now applies to ActorState objects
13522
as well as to ConvNode objects.  Suggestions are effectively arranged
13523
into a hierarchy: the top level of the hierarchy is the ConvNode, the
13524
next level is the ActorState, and the bottom level is the Actor.
13525
The full list of suggestions consists of the ConvNode's suggestions,
13526
plus the ActorState's suggestions, plus the Actor's suggestions.
13527
However, if limitSuggestions is true at any level of the hierarchy,
13528
then suggestions below that point are not included in the full list.
13529
So, if the ConvNode's limitSuggestions property is true, only the
13530
ConvNode suggestions are included.  If the ConvNode's limitSuggestions
13531
property is nil, but the ActorState's limitSuggestions property is
13532
true, then the ConvNode and ActorState suggestions are both included.
13533
If limitSuggestions is nil for both the ConvNode and ActorState, then
13534
the suggestions at all three levels (ConvNode, ActorState, and Actor)
13535
are included in the full list.
13536
13537
</div>
13538
13539
<!------------------->
13540
<div class=entry>
13541
13542
The new class SuggestedTopicTree makes it easy to create a tree of
13543
AltTopic alternatives that acts as a single suggested topic.
13544
13545
<p>Normally, when you create a tree of AltTopic alternatives,
13546
you can make each AltTopic a separate suggestion.  Each alternative
13547
is effectively an independent topic for suggestion purposes, so
13548
asking about one doesn't satisfy the PC's curiosity about any of
13549
the other alternatives.  This means that the game might make the
13550
same suggestion several times, as the different alternatives become
13551
active.
13552
13553
<p>In many cases, it's better to treat the whole group of alternatives
13554
as a single suggestion, so that the suggestion is only made once (or
13555
only as many times as desired) for the whole set.  This is what
13556
SuggestedTopicTree is for.  To use this class, simply add SuggestedTopicTree
13557
to the superclass list for the <b>main</b> TopicEntry (that is, the
13558
TopicEntry at the root of the tree: the one containing all of the
13559
AltTopic alternatives).
13560
13561
<p>Note that the new TopicEntry property altTalkCount keeps track of
13562
the number of invocations for an entire alternative group.  This
13563
property is kept in the outermost TopicEntry for an AltTopic group,
13564
and is incremented each time the outermost TopicEntry or any of its
13565
AltTopic objects is invoked (via ASK ABOUT, TELL ABOUT, etc).
13566
SuggestedTopicTree uses this new counter to determine if the PC's
13567
curiosity has been satisfied for the set of alternatives as a group.
13568
13569
</div>
13570
13571
<!------------------->
13572
<div class=entry>
13573
13574
The former ConversationManager method setRespondingActor() has been
13575
renamed to beginResponse(), and a new method finishResponse() has been
13576
added.  Each call to beginResponse() should have a corresponding call
13577
to finishResponse().
13578
13579
<p>This change allows the conversation manager to defer setting the
13580
new default ConvNode in the responding actor until after the response
13581
has been finished.  This ensures that a ConvNode's noteActive()
13582
method will not be invoked in response to a &lt;.convstay&gt; tag.
13583
In the past, the conversation manager immediately transitioned the
13584
actor to the default next ConvNode at the start of showing the
13585
response, so if the response contained a &lt;.convstay&gt; tag, this
13586
caused a transition back to the starting ConvNode, and thus a call to
13587
noteActive() on the ConvNode object.  The new scheme ensures that the
13588
actor's ConvNode won't change at all when processing a
13589
&lt;.convstay&gt; tag.
13590
13591
</div>
13592
13593
<!------------------->
13594
<div class=entry>
13595
13596
The AgendaItem class has a new method, resetItem(), that is invoked
13597
each time the item is added to an actor's agenda (via
13598
Actor.addToAgenda()).  By default, this method sets the item's isDone
13599
property to nil, as long as the property isn't a method.  This makes
13600
it easier to re-use agenda items, since you don't have to worry about
13601
resetting isDone explicitly.
13602
13603
</div>
13604
13605
<!------------------->
13606
<div class=entry>
13607
13608
The Surface class now uses a custom Lister,
13609
surfaceInlineContentsLister, to show its in-line contents listing.
13610
The new lister shows the in-line contents using the format "(on which
13611
is...)".  In the past, Surface simply inherited Thing's in-line
13612
contents lister, which phrases things in terms of containment
13613
("(which contains...)"), which isn't quite right for surfaces.
13614
13615
<p>For naming consistency, the Lister formerly named
13616
keyringListingContentsLister has been renamed to
13617
keyringInlineContentsLister.  The old name was a bit odd and didn't
13618
properly call attention to the "in-line" aspect.
13619
13620
</div>
13621
13622
<!------------------->
13623
<div class=entry>
13624
13625
Whenever an object's contents are listed via EXAMINE, LOOK IN, or
13626
OPEN, the library now automatically marks all of the object's visible
13627
contents as having been seen.  Only contents that are actually
13628
visible to the character performing the command will be marked as
13629
seen, but it doesn't matter whether or not the contents are mentioned
13630
at all in the description of the object.
13631
13632
</div>
13633
13634
<!------------------->
13635
<div class=entry>
13636
13637
The new Thing method useSpecialDescInRoom(room) lets an object specify
13638
whether or not its special description should be shown in a LOOK AROUND
13639
description.  By default, this simply returns useSpecialDesc().  In
13640
some cases, it might be desirable for an object to show its special
13641
description only when a container is examined, but not in a room
13642
description; this methods lets the object control this.
13643
13644
</div>
13645
13646
<!------------------->
13647
<div class=entry>
13648
13649
<p>The new Thing property suppressAutoSeen can be used to suppress
13650
the library's automatic "seen" marking.  By default, the library
13651
automatically marks every visible object as having been seen whenever
13652
a LOOK AROUND command is performed.  The library also automatically
13653
marks as seen every visible object within a container when the
13654
container is explicitly examined (with EXAMINE, LOOK IN, or OPEN, for
13655
example).
13656
13657
<p>suppressAutoSeen is nil by default.  If you set it to true for an
13658
object, then the library will not mark the object as having been seen
13659
in any of the standard cases, even when the object is visible.  The
13660
game must mark the object as having been seen by explicitly calling
13661
setSeenBy(), if and when desired.
13662
13663
</div>
13664
13665
<!------------------->
13666
<div class=entry>
13667
13668
DistanceConnector now derives from Intangible as well as
13669
SenseConnector.  This makes it easier to use DistanceConnector, since
13670
it's no longer necessary to mix it with a Thing subclass.  Each
13671
distance-connector object needs to derive from Thing so that it fits
13672
into the normal sense model, but these objects will almost never have
13673
any physical presence in the game; Intangible fills both of these
13674
needs.
13675
13676
</div>
13677
13678
<!------------------->
13679
<div class=entry>
13680
13681
The DistanceConnector template in adv3.h, which sets the locationList
13682
property, has been changed into a generic MultiLoc template.  This
13683
lets you initialize any MultiLoc object's location list by specifying
13684
the list of locations after the class name when defining the object.
13685
13686
</div>
13687
13688
<!------------------->
13689
<div class=entry>
13690
13691
The Room template in en_us/en_us.h now accepts a room that defines
13692
only a 'name' property; the 'desc' property is now optional.  This
13693
lets you use the template to define the room name even if you want
13694
to define a complex method for the 'desc'.
13695
13696
</div>
13697
13698
<!------------------->
13699
<div class=entry>
13700
13701
A bug in the Sense class incorrectly considered objects to be out of
13702
range of the 'smell' and 'sound' senses when the objects had distant,
13703
obscured, or attenuated sense paths.  This has been corrected.
13704
13705
</div>
13706
13707
<!------------------->
13708
<div class=entry>
13709
13710
A Door object's getDoorOpenPreCond() can now return nil, if it's
13711
not desirable to use a precondition for opening the door.
13712
13713
</div>
13714
13715
<!------------------->
13716
<div class=entry>
13717
13718
The BasicChair, BasicBed, and BasicPlatform classes now include
13719
a touchObj precondition for the SIT ON, LIE ON, and STAND ON commands.
13720
13721
</div>
13722
13723
<!------------------->
13724
<div class=entry>
13725
13726
Where it makes sense, the preconditions that report failures with
13727
messages along the lines of "You must open (something) first" now set
13728
the pronoun antecedent to the object mentioned.  This makes exchanges
13729
like this work as one would expect:
13730
13731
<p><pre>
13732
  &gt;north
13733
  You must open the door first.
13734
13735
  &gt;open it
13736
</pre>
13737
13738
</div>
13739
13740
<!------------------->
13741
<div class=entry>
13742
13743
In the hint system's Goal class, the new properties openWhenKnown and
13744
closeWhenKnown let you tie a hint topic to the player character's
13745
knowledge of a Topic or Thing.  If you set a Goal object's
13746
openWhenKnown to refer a Topic or Thing, then the Goal will become
13747
"open" as soon as the Topic or Thing becomes known to the PC.
13748
Likewise, if you set closeWhenKnown to a Topic or Thing, the goal
13749
will become "closed" when the Topic or Thing becomes known.
13750
13751
<p>The new Goal properites openWhenRevealed and closeWhenRevealed
13752
let you tie a hint to a &lt;.reveal&gt; tag.  You can set these
13753
properties to (single-quoted) strings giving &lt;.reveal&gt; tags
13754
to test.
13755
13756
</div>
13757
13758
<!------------------->
13759
<div class=entry>
13760
13761
The Goal class has two new methods, openWhen and closeWhen, that
13762
compute the conditions for opening and closing the hint topic,
13763
respectively.  These methods isolate the conditions that were
13764
formerly included in-line in the updateContents() method.  
13765
13766
<p>Isolating the conditions in separate methods makes it easier to
13767
use 'modify Goal' to add new custom open/close sub-conditions.  For
13768
example, suppose you wanted to add a pair of new custom Goal
13769
properties that open and close hint topics based on a Thing being
13770
moved for the first time.  You could do this like so:
13771
13772
<p><pre>
13773
  modify Goal
13774
    openWhenMoved = nil
13775
    closeWhenMoved = nil
13776
    openWhen = (inherited || (openWhenMoved != nil &amp;&amp; openWhenMoved.moved))
13777
    closeWhen = (inherited || (closeWhenMoved != nil &amp;&amp; closeWhenMoved.moved))
13778
  ;
13779
</pre>
13780
13781
</div>
13782
13783
<!------------------->
13784
<div class=entry>
13785
13786
The new library function intOrdinal(n) returns a "numeric ordinal"
13787
representation of the number: '1st', '2nd', '3rd', and so on.
13788
(Thanks to Søren J. Løvborg for suggesting this and providing a
13789
sample implementation.)  
13790
13791
<p>Along the same lines, the new library functions spellIntOrdinal(n)
13792
and spellIntOrdinalExt(n, flags) return fully spelled-out ordinals
13793
('first', 'second', 'third', etc).  The 'Ext' version takes the same
13794
bit-flag values as spellIntExt().
13795
13796
</div>
13797
13798
<!------------------->
13799
<div class=entry>
13800
13801
The library no longer considers the player character to be an
13802
antecedent to a third-person pronoun when the game itself refers to
13803
the PC in the first or second person (as determined by the PC Actor's
13804
referralPerson property).  In the past, typing X ME and then X IT
13805
examine the player character twice.  This will no longer happen,
13806
except in third-person games, since the first X ME won't set ME as an
13807
antecedent for HIM, HER, IT, or THEM.  This isn't especially important
13808
for IT and THEM, but it can be for HIM and HER if the PC has a specified
13809
gender.
13810
13811
</div>
13812
13813
<!------------------->
13814
<div class=entry>
13815
13816
The library now treats HIM and HER a little differently in disambiguation
13817
responses.  If HIM or HER is given as the answer to a disambiguation
13818
question ("which one do you mean..."), the parser first looks to see
13819
if there's a prior meaning of the pronoun that applies; it always did
13820
this much.  This is the new part: if there is no prior meaning for
13821
the pronoun, or the prior meaning isn't one of the choices in the
13822
query, then the parser looks to see if any of the objects in the query
13823
match the pronoun.  If there's exactly one match, the parser takes that
13824
as the result.
13825
13826
</div>
13827
13828
<!------------------->
13829
<div class=entry>
13830
13831
The English library module defines a few new methods related to
13832
pronouns and gender.  The new Thing methods canMatchHim, canMatchHer,
13833
canMatchIt, and canMatchThem determine if an object can match these
13834
individual pronouns.  By default, these simply return true if the
13835
corresponding isHim/isHer/isIt flags are true.  Actor overrides these
13836
so that they return true if the inherited version returns true
13837
<i>and</i> the actor can be referred to in the third person, which is
13838
determined by testing the additional new Actor method
13839
canMatch3rdPerson.  The new canMatch3rdPerson method returns true if
13840
the actor isn't the player character, <i>or</i> the game refers to
13841
the PC in the third person.
13842
13843
</div>
13844
13845
<!------------------->
13846
<div class=entry>
13847
13848
The former Actor methods canTouch(obj) and findTouchObstructor(obj)
13849
have been moved to Thing.  There wasn't any need for these methods to
13850
be special to Actor, and it's sometimes useful to establish
13851
reachability between arbitrary non-Actor objects, so these are more
13852
appropriate for Thing than Actor.
13853
13854
</div>
13855
13856
<!------------------->
13857
<div class=entry>
13858
13859
The new class TouchObjCondition implements a generic object-to-object
13860
reachability condition.  This is similar to the existing touchObj
13861
pre-condition, but allows for arbitrary source objects, whereas
13862
touchObj can only test to see if the current gActor can touch an
13863
object.  touchObj is now a subclass of TouchObjCondition.
13864
13865
</div>
13866
13867
<!------------------->
13868
<div class=entry>
13869
13870
In the past, throwing an object at a MultiLoc object, or at a component
13871
within a MultiLoc object, didn't work properly.  This has been corrected.
13872
13873
<p>In order to allow throwing at MultiLoc objects, the interface to a
13874
Thing method, getDropDestination, has been altered slightly.  This
13875
method now takes an additional parameter giving the "sense path" that
13876
was used in the operation that's seeking the drop destination.  The
13877
new sense path parameter is a list in the same format returned by
13878
Thing.selectPathTo.  This path information allows getDropDestination
13879
to determine whence the MultiLoc object was approached - that is, it
13880
allows a MutliLoc object to find out which of its containers or
13881
containment peers was last traversed to reach the object.  This path
13882
can be nil, but when it's supplied, it tells us how we're approaching
13883
the drop destination.
13884
13885
<p>Note that this change slightly affects the interfaces to several
13886
Thing methods: getHitFallDestination, throwTargetHitWith,
13887
stopThrowViaPath, throwViaPath, and throwTargetCatch.  In all of these
13888
routines, the former 'prvCont' parameter is now replaced with the
13889
'path' parameter.  Similarly, the processThrow method passes the path
13890
rather than the previous container.
13891
13892
</div>
13893
13894
<!------------------->
13895
<div class=entry>
13896
13897
In the English grammar, abbreviated words that include periods in the
13898
abbreviation (as in "Main St." or "J. Pretensions") are now treated a
13899
little differently, to ensure that abbreviated words don't have any
13900
bad interactions with unabbreviated equivalents.  This change should
13901
be completely transparent to existing game code.
13902
13903
<p>First, the tokenizer no longer treats an abbreviation as a single
13904
token that includes the period, but rather as two separate tokens:
13905
one for the word itself, and a separate token for the period.  The
13906
period is entered not with the ordinary punctuation token class, but
13907
with the new 'tokAbbrPeriod' class.  Second, wherever ordinary noun
13908
tokens were allowed in the grammar, the grammar now instead accepts
13909
the new subproduction 'nounWord'.  This new production matches an
13910
ordinary noun token, <i>or</i> a noun token followed by a
13911
tokAbbrPeriod token.  Third, and similarly, the existing 'adjWord'
13912
production now accepts an adjective token followed by a tokAbbrPeriod
13913
token.  Fourth, the vocabulary initialization
13914
(VocabObject.initializeVocabWith, which parses the vocabWords_
13915
string) now enters each token that ends in a period with the period,
13916
as it did, but also <i>without</i> the period.  So, for example, the
13917
vocabWords_ string 'main st.' will create an adjective 'main', a noun
13918
'st.', and a second noun 'st' (in other words, 'st' is entered in the
13919
dictionary both with and without a trailing period).
13920
13921
<p>This corrects a problem that could have occurred with the old
13922
scheme if the same word was used abbreviated and unabbreviated.  For
13923
example, if 's.' was used as an abbreviated word (for a string like
13924
's. main st.', for example), and 's' was also entered in the
13925
dictionary as a verb (which it is by default, for the South action)
13926
the command "s." was not properly handled.  The problem was that the
13927
tokenizer would see that "s." was entered in the dictionary with the
13928
period, so it tokenized it with the period.  This precluded
13929
interpreting it as two tokens, 's' and '.', so the 's' was not
13930
matched to the verb, hence the command was rejected as not understood.
13931
13932
<p>A useful side effect of this change is that each abbreviation is
13933
now automatically entered in the dictionary without its period.  This
13934
should be helpful to players who choose to avoid the extra typing of
13935
entering the periods in abbreviations.
13936
13937
</div>
13938
13939
<!------------------->
13940
<div class=entry>
13941
13942
The new Hidden class can be used to implement objects that are present
13943
but not seen.  This is useful for objects that are too inconspicuous
13944
to be noticed, or are positioned in such a way that they can't be
13945
readily seen (but in such a way that the ordinary sense mechanism
13946
would think the object was visible).
13947
13948
</div>
13949
13950
<!------------------->
13951
<div class=entry>
13952
13953
The BulkLimiter class now parameterizes all of the messages that
13954
were previously coded directly as failure reports.  The new BulkLimiter
13955
properties tooLargeMsg, becomingTooLargeMsg, and becomingTooFullMsg
13956
join the existing tooFullMsg in specifying the various failure reports;
13957
these properties in turn contain property pointers that refer to
13958
messages defined in the playerActionMessages object.  This makes it
13959
easier to create "cosmetic" subclasses of BulkLimiter that define
13960
customized types of containment relationships.
13961
13962
</div>
13963
13964
<!------------------->
13965
<div class=entry>
13966
13967
The new macro askForTopic(action) allows a single-object TAction to
13968
ask for a topic phrase and retry the command as a TopicTAction.  This
13969
allows, for example, a CONSULT action with no topic specified to ask
13970
for a topic and turn itself into a CONSULT ABOUT action.
13971
13972
<p>To enable this change, the parser includes a new grammar
13973
production, EmptyTopicPhrase.  This new production represents a topic
13974
phrase that requires an interactive response from the player.
13975
13976
</div>
13977
13978
<!------------------->
13979
<div class=entry>
13980
13981
In the past, it wasn't possible to use askForDobj() to convert a
13982
LiteralAction into a LiteralTAction, or a TopicAction into a
13983
TopicTAction, by requesting a missing direct object from the player.
13984
This was due to an oversight in the library, which has now been
13985
corrected.
13986
13987
<p>Another similar, though more subtle, oversight made it impossible
13988
to use askForDobj() to convert a TAction into a TIAction.  This is an
13989
unusual scenario, because the usual way to perform this conversion
13990
would be through askForIobj(): it's almost always the indirect object
13991
that's missing in these cases.  However, there are cases where a
13992
missing direct object is possible; for example, we might want a
13993
full-fledged SPRAY verb that takes only one object, as in SPRAY AIR
13994
FRESHENER, but also have a two-object form for things like SPRAY SINK
13995
WITH DISINFECTANT, in which it's the direct object that's missing
13996
from the two-object form when we type SPRAY DISINFECTANT.  (This
13997
particular example is a bit contrived, since we could just as well
13998
have defined the verb as SPRAY DISINFECTANT ON SINK, but even so, we
13999
don't want to be forced to find such a rephrasing.)  In these cases,
14000
askForDobj() can now be used.  When a TAction is retried as a
14001
TIAction with askForDobj(), the direct object of the TAction now
14002
becomes the <i>indirect</i> object of the TIAction; this is plainly
14003
the only way it can be, since we know the direct object is missing by
14004
virtue of the fact that we're asking for it.
14005
14006
</div>
14007
14008
<!------------------->
14009
<div class=entry>
14010
14011
The interface of the method Actor.trackFollowInfo() has been changed
14012
slightly to improve its flexibility.  In the past, this method assumed
14013
that the current action was actually performing the travel; now, the
14014
method instead takes an additional argument to eliminate this
14015
dependency.  The new third argument gives the starting location of the
14016
travel; this is normally simply the location of the actor traveling,
14017
but could be something else; for example, when the actor is inside
14018
a vehicle, then the starting location is the vehicle's location.
14019
14020
</div>
14021
14022
<!------------------->
14023
<div class=entry>
14024
14025
The new class NestedRoomFloor can be used for convenience in creating
14026
an object that serves as the floor of a nested room.
14027
14028
</div>
14029
14030
<!------------------->
14031
<div class=entry>
14032
14033
The Floor class now accepts STAND ON commands.  STAND ON FLOOR is 
14034
simply remapped to STAND UP.
14035
14036
</div>
14037
14038
<!------------------->
14039
<div class=entry>
14040
14041
The BurnWith action now resolves its direct object first.  This is
14042
the better resolution order for this action, since it allows the
14043
direct object to set the scope for choosing the indirect object,
14044
which is likely to be omitted and thus require a suitable default
14045
to be chosen.
14046
14047
<p>In addition, the FireSource class now declares it illogical to
14048
burn an object using itself as the fire source.  It's common for a
14049
Candle to also be a FireSource; this change prevents such an object
14050
from being chosen as its own default fire source in a command like
14051
LIGHT CANDLE, which would cause an infinite loop as we tried to light
14052
the candle with itself, which would require first lighting the
14053
candle, which would default to lighting it with itself again, and so
14054
on.
14055
14056
<p>The FireSource and Matchstick classes have also been fine-tuned to
14057
work together a little better.  The FireSource class now specifies a
14058
logicalRank of 150 when used as the indirect object of BurnWith.  The
14059
Matchstick class uses a logical rank of 160 when lit and 140 when not
14060
lit.  This makes a matchstick an especially logical choice for
14061
starting a fire under all conditions, but makes a non-matchstick an
14062
even better choice when it's already burning.  A lit match trumps
14063
everything (160), next best is an already-lit non-matchstick
14064
FireSource (150), and when there's nothing else around that's
14065
burning, a matchstick will still be a good choice (140).  This
14066
ensures that we don't light a new match when there's another fire
14067
source readily at hand, but at the same time ensures that we'll
14068
default to using a match when no better choice is available.
14069
14070
</div>
14071
14072
<!------------------->
14073
<div class=entry>
14074
14075
When an implicit action is interrupted with an interactive prompt,
14076
the announcement of the implicit action is now phrased as "trying"
14077
the action.  This is along the same lines as the change in 3.0.6k
14078
that phrased failed implicit actions as "trying"; since an interactive
14079
prompt interrupts an implied action, it makes more sense to refer to
14080
the implied action as being merely attempted at this stage.
14081
14082
<p>Internally, the announcement generator distinguishes between
14083
failed actions and actions interrupted for interactive input, so it's
14084
a fairly easy matter to customize the types of messages separately.
14085
To customize the "asking" case separately from the "trying" case,
14086
customize the askingImpCtx object; in particular, override its
14087
buildImplicitAnnouncement() method and its useInfPhrase property as
14088
needed.  The default in the library is to use the same message
14089
style for both cases.
14090
14091
</div>
14092
14093
<!------------------->
14094
<div class=entry>
14095
14096
Due to a bug in the library, using "exit" to abort an action from
14097
within a check() handler did not properly mark the action as failed
14098
within the transcript, which meant that the "trying" form of an
14099
implicit action announcement was not generated.  This has been
14100
corrected.
14101
14102
</div>
14103
14104
<!------------------->
14105
<div class=entry>
14106
14107
In the past, when an implied action was remapped to another action
14108
(via remapTo), the normal announcement of the implied action wasn't
14109
generated.  This has been corrected: the announcement will now be
14110
shown as usual.
14111
14112
</div>
14113
14114
<!------------------->
14115
<div class=entry>
14116
14117
The parser is now a little smarter about excluding items with ALL
14118
EXCEPT in cases of simple remappings.  In many cases, remapTo is used
14119
to create simple object-to-object synonyms for certain verbs; for
14120
example, OPEN DESK might be remapped to OPEN DRAWER when it's obvious
14121
that the two commands mean the same thing.  In these cases, when an
14122
object is excluded from the ALL list with EXCEPT, the parser will now
14123
look for these simple synonym remappings, and it will treat them as
14124
equivalent.  So, if OPEN DESK is remapped to OPEN DRAWER, and the
14125
player types OPEN ALL BUT DESK or OPEN ALL BUT DRAWER, then the desk
14126
and drawer will be excluded from the ALL list.
14127
14128
<p>Note that the parser can only exclude synonym remappings when
14129
they're remapped using the remapTo (or maybeRemapTo) mechanism.
14130
Remappings that are done using replaceAction() or the like can't
14131
be detected as synonyms, so they won't be excluded.  Remappings
14132
that aren't simple synonyms won't be excluded, since remapping
14133
to different verbs or word orders changes the meaning of the
14134
command enough that the EXCEPT list shouldn't exclude the new
14135
objects.  For example, if OPEN DOOR remaps to PUSH BUTTON, because
14136
a button is used to operate a mechanical door, OPEN ALL BUT BUTTON
14137
would <b>not</b> exclude the remapping to PUSH BUTTON, since we
14138
didn't say not to PUSH the button, only not to OPEN the button.
14139
14140
</div>
14141
14142
<!------------------->
14143
<div class=entry>
14144
14145
The standard "weak vocabulary" checking in Thing now takes into account
14146
truncatable vocabulary words, as well as any other special dictionary
14147
comparison rules, by using the main dictionary's string comparator
14148
to check for weak tokens.  Note that this routine uses the global
14149
property languageGlobals.dictComparator, so if the game ever changes
14150
the main dictionary's string comparator object, it should also change
14151
this global property at the same time.
14152
14153
</div>
14154
14155
<!------------------->
14156
<div class=entry>
14157
14158
The Topic class now specifically disallows sensing a topic object
14159
with any physical senses.  This ensures that a topic object will
14160
never be in any physical scope, even if the object is part of a
14161
containment hierarchy.  (It's sometimes convenient to include a topic
14162
as part of a containment hierarchy in order to associate the topic
14163
with a physical game world object.)
14164
14165
</div>
14166
14167
<!------------------->
14168
<div class=entry>
14169
14170
The possessive qualifier resolver (PossessiveResolver) now considers
14171
an object to be in scope in a possessive phrase only if the object
14172
has the property canResolvePossessive set to true.  This property is
14173
true by default for all Things and nil by default for all Topics.  In
14174
other words, by default, possessive phrase qualifiers can only be
14175
resolved to physical game world objects, never to abstract topics.
14176
14177
</div>
14178
14179
<!------------------------------- 3.0.6k --------------------------------->
14180
<div class="sepbar"><a name='306k'></a>3.0.6k</div>
14181
<p><b><i>Released August 17, 2003</i></b>
14182
<p>
14183
14184
<div class=firstentry>
14185
14186
The new TopicEntry method isMatchPossible() tries to guess whether or
14187
not the TopicEntry can be matched by any input currently.  This
14188
question is unanswerable in general, because it's asking if there
14189
exists any input, out of the infinite set of possible inputs, that
14190
will match the topic entry.  However, the TopicEntry subclasses use
14191
heuristics to provide an answer that's right in most cases.  In
14192
particular, the ASK and TELL entries consider themselves matchable if
14193
any of their matchObj objects are either known to the player character
14194
or are simply in scope; the GIVE and SHOW entries are considered
14195
matchable if any of their matchObj objects are in scope; and YES, NO,
14196
and special topic entries are always considered matchable.  If a game
14197
creates a custom matchTopic() method, it might want to customize
14198
isMatchPossible() to match the custom match condition.
14199
14200
<p>The SuggestedTopic method isSuggestionActive() uses this new
14201
method to hide suggestions that aren't currently matchable.  This
14202
provides an important benefit for the most common cases: topics won't
14203
be suggested until the player character knows about them.  This
14204
avoids showing suggestions for things the player shouldn't even
14205
have heard of yet.
14206
14207
<p>To facilitate this change, isSuggestionActive() now takes an
14208
additional argument, giving the list of in-scope objects.  This
14209
avoids the need to repeatedly compute the scope list when scanning
14210
a large list of suggested topic objects, which is important because
14211
the scope calculation is complex and can be time-consuming.
14212
14213
</div>
14214
14215
<!------------------->
14216
<div class=entry>
14217
14218
Some important terminology for TopicEntry objects has been changed:
14219
where we formerly referred to a TopicEntry as "known," we now refer to
14220
it as "active" instead.  The old terminology implied that TopicEntry
14221
objects model NPC knowledge; this was misleading, though, because the
14222
availability of a TopicEntry often depends on PC knowledge as well as
14223
NPC knowledge, or what the NPC <i>wishes</i> to reveal rather than
14224
what the NPC actually knows, or various other things.  The new
14225
terminology removes the implication that NPC knowledge in particular
14226
is being modeled.
14227
14228
<p>This change requires new names for several TopicEntry properties:
14229
isKnown is now isActive; checkIsKnown is now checkIsActive; and
14230
topicGroupKnown is now topicGroupActive.
14231
14232
<p>Game code that uses TopicEntry objects will have to rename isKnown
14233
to isActive in the object definitions.  The other renamed properties
14234
might have to be changed as well, of course, but these are less likely
14235
to appear in game code.
14236
14237
</div>
14238
14239
<!------------------->
14240
<div class=entry>
14241
14242
The travel precondition mechanism has been tweaked a little to make it
14243
more flexible for handling nested-room situations.  In the past, each
14244
travel connector was responsible for providing a precondition applied
14245
whenever an actor traversed the connector, via the travel connector's
14246
actorTravelPreCond(actor) method.  This formerly returned the
14247
actorStanding precondition.  While this was appropriate in most cases,
14248
since it ensured that the actor wasn't sitting in a chair or anything
14249
like that, it didn't make for easy customization for specialized nested
14250
rooms or other unusual situations.
14251
14252
<p>The change is that TravelConnector.actorTravelPreCond(actor) now
14253
returns a new precondition, actorTravelReady, instead of
14254
actorStanding.  The actorTravelReady precondition abstracts the travel
14255
condition by letting the actor's immediate location handle it.  In
14256
particular, it calls three new BasicLocation methods to carry out the
14257
precondition: isActorTravelReady(conn), tryMakingTravelReady(conn),
14258
and notTravelReadyMsg.  By default, these methods do exactly what
14259
actorStanding does: they require the actor to be standing up before
14260
travel.  However, a location can override any or all of these.  For
14261
example, a particular nested room might want to use a command other
14262
than "stand up" to get the actor out of the nested room in preparation
14263
for travel; the nested room could override tryMakingActorTravelReady()
14264
in this case to carry out the desired implied command.
14265
14266
<p>Note that the travel connector to be traversed is an argument to
14267
the first two of the new methods.  This allows the actor's current
14268
location to impose different requirements on travel via different
14269
connectors.  For example, it might be necessary to climb down from a
14270
ladder before leaving via any connector except for a window high up on
14271
the wall, which can only be reached when on the ladder.
14272
14273
</div>
14274
14275
<!------------------->
14276
<div class=entry>
14277
14278
The new Action method cancelIteration() lets you tell cancel further
14279
iteration of the current action, if multiple objects are involved in
14280
the action.  You can call this method on the current gAction object
14281
during the 'check' or 'action' phases of execution.  Once the method
14282
is called, the action will complete the execution cycle for the
14283
current object as normal, but it will then act as though the current
14284
object were the last object of the command.
14285
14286
<p>Note that this new method does <b>not</b> have any effect on the
14287
execution of the command for the current object; in particular, it
14288
doesn't interrupt the execution flow the way 'exit' and the like do.
14289
Instead, this method simply sets a flag in the current Action object
14290
telling it to ignore any additional objects it would otherwise
14291
iterate over.  If you want to jump out of the execution cycle in
14292
addition to canceling further iteration, simply use 'exit' (or one of
14293
the similar signals) after calling this method.  Note also that this
14294
method obviously can't cancel the iteration for any prior objects in
14295
the iteration.
14296
14297
</div>
14298
14299
<!------------------->
14300
<div class=entry>
14301
14302
In the status-line and menu modules, there were some unnecessary
14303
"flush" operations (on banners and on the main window).  Most of these
14304
were placed before "sizeToContents" calls on banners, which is
14305
unnecessary because that operation automatically flushes the
14306
underlying output stream anyway.  These extra calls were not only
14307
unnecessary but were also undesirable, because the explicit flush
14308
operations always update the display immediately in addition to
14309
flushing internal text buffers.  This made the display flicker
14310
annoyingly at times.  The extra flushes have been removed, which
14311
makes the display updating faster and eliminates the flicker in
14312
the common cases covered by the changes.
14313
14314
</div>
14315
14316
<!------------------->
14317
<div class=entry>
14318
14319
When a MenuLongTopicItem is part of a series of "chapters" (as
14320
indicated by the isChapterMenu property), and the user navigates
14321
directly from one chapter to the next, the menu system keeps the
14322
banner configuration for the chapter display throughout the change
14323
to the new chapter.  In the past, the menu system removed the banner
14324
and then immediately restored it, which caused some visual flicker.
14325
This change eliminates the flicker during the chapter change.
14326
14327
</div>
14328
14329
<!------------------->
14330
<div class=entry>
14331
14332
The English implicitAnnouncementGrouper implementation now uses
14333
pronouns, where appropriate, to refer to repeated objects when it
14334
groups a series of announcements.  It frequently happens that the same
14335
object appears more than once when a series of implied actions is
14336
performed; this new phrasing makes the announcement text shorter and
14337
makes it read more naturally.  For example, rather than saying "first
14338
unlocking the door, then opening the door", we'll now say "first
14339
unlocking the door, then opening it".
14340
14341
</div>
14342
14343
<!------------------->
14344
<div class=entry>
14345
14346
The implicit action announcement mechanism now phrases the
14347
announcement for a failed action a little differently than for a
14348
successful action.  When an action fails, the message now reads
14349
"(first trying to ...)".  The old phrasing was a little awkward at
14350
times, because the announcement describes the action as being
14351
performed, and then the (usually) very next message says just the
14352
opposite, that the action wasn't performed at all because it failed.
14353
Depending on the wording of the failure message, the combination could
14354
even be misleading on occasion, since the suggestion in the
14355
announcement that the action was performed could lead to a player
14356
assuming that the failure message must refer to something else.
14357
14358
<p>To enable this change, the interface to the libMessages method
14359
announceImplicitAction() has changed slightly.  The method now takes a
14360
"context" parameter, which is an object of class
14361
ImplicitAnnouncementContext The context contains information on the
14362
format of the message to be generated.
14363
14364
<p>Also, the implicitGroupTransform internally scans for failure
14365
messages that apply to implied action announcements, and rewrites the
14366
implied action announcements into the new format when failures are
14367
noted.
14368
14369
<p>Finally, the implicitAnnouncementGrouper object implementation in
14370
the English module does some additional grouping, to render a series
14371
of "trying" messages as readably as possible.  When a series of
14372
consecutive "trying" messages appears, the grouper combines them under
14373
a single "trying" phrase, as in "first trying to unlock the door and
14374
then open it."
14375
14376
</div>
14377
14378
<!------------------->
14379
<div class=entry>
14380
14381
Several small internal changes have been made in the English library
14382
module.
14383
14384
<p>First, the new method getInfPhrase() returns a string giving the
14385
full action description in infinitive form.  This returns a phrase
14386
such as "open the box" or "unlock the door with the key".  The verb is
14387
always in the infinitive form, but note that the English infinitive
14388
complementizer, "to", is not part of the returned phrase; this is
14389
because an infinitive is used without a complementizer in certain
14390
contexts in English, such as with auxiliary verbs (such as "might" or
14391
"should").
14392
14393
<p>Second, the new method getVerbPhrase(inf, ctx) returns the full
14394
verb phrase in either the infinitive form ("open the box") or the
14395
present participle form ("opening the box").  In English, the two
14396
forms are equivalent except for the verb ending, so the code to
14397
generate both forms can be easily consolidated into a single routine.
14398
The subclasses of Action override getVerbPhrase() as needed to provide
14399
appropriate phrasings.  The context object 'ctx' is optional; if it's
14400
not nil, it should be an instance of the new class
14401
GetVerbPhraseContext.  If the context object is provided, the routine
14402
uses it to keep track of pronoun antecedents for the verb phrase; the
14403
returned verb phrase will use a pronoun if one of its objects matches
14404
the current antecedent, and the routine will set the antecedent in the
14405
context for the next verb phrase that uses the same context.  The
14406
context is useful if you're generating a series of verb phrases that
14407
you're going to string together into a single sentence; by using
14408
pronouns to refer to repeated objects, the sentence will be shorter
14409
and will read more naturally.
14410
14411
<p>Third, the implementation of getParticiplePhrase() now simply
14412
calls getVerbPhrase() in all cases.
14413
14414
<p>Fourth, the routine formerly called verbInf() has been renamed to
14415
getQuestionInf(), to better describe its purpose.  This routine
14416
doesn't return the full infinitive form of the verb, but rather
14417
returns an infinitive form specifically for an interrogative in which
14418
one of the verb's objects is the interrogative's unknown.  The old
14419
name was always misleading, but the addition of getInfPhrase() would
14420
have made the name even more confusing because of the similarity of
14421
the names.
14422
14423
</div>
14424
14425
<!------------------->
14426
<div class=entry>
14427
14428
In the routine that tries to free up space in an actor's hands by
14429
moving objects into a "bag of holding," objects with no encumbering
14430
bulk are now never moved.  In the past, objects were moved in
14431
descending order of encumbering bulk, so objects with zero bulk were
14432
typically ignored; however, if there weren't enough bulky objects
14433
present, it was possible for the routine to try moving bulkless items.
14434
Since worn items have no encumbering bulk by default, this meant the
14435
routine sometimes removed worn items and moved them to the bag, which
14436
was pointless.
14437
14438
</div>
14439
14440
<!------------------->
14441
<div class=entry>
14442
14443
The new class FloorlessRoom, a subclass of Room, makes it easier to
14444
build rooms that represent locations without conventional floors.
14445
Anything dropped in the room is described as falling and vanishing
14446
below, since there's no floor for it to land on.  You can control
14447
where dropped objects land using the bottomRoom property; by default,
14448
this is nil, which means that dropped objects simply disappear
14449
from the game.
14450
14451
</div>
14452
14453
<!------------------->
14454
<div class=entry>
14455
14456
The Room class no longer requires the room's floor to be represented
14457
by the first element of the roomParts list for the room.  Instead, the
14458
new method roomFloor returns the room's floor object; this method
14459
finds an object of class Floor in the roomParts list and returns it,
14460
or nil if there no object of class Floor in the list.  This change
14461
eliminates the fragility caused by the former convention.
14462
14463
</div>
14464
14465
<!------------------->
14466
<div class=entry>
14467
14468
A new mechanism provides more consistent handling when objects
14469
are dropped into a room.  The new mechanism is used in the library
14470
to handle the DROP and THROW commands, both of which can result in
14471
an object being dropped into the enclosing room.  The mechanism is
14472
extensible, so library extensions and games can add their own actions
14473
that drop objects into the room.
14474
14475
<p>Whenever an object is to be dropped into the enclosing room, the
14476
DROP and THROW commands first find the drop destination using the
14477
existing getDropDestination() method.  Then, they invoke the new
14478
receiveDrop(obj, desc) method on the drop destination object.  In most
14479
cases, the drop location is the enclosing room, so the enclosing
14480
room's receiveDrop() method is usually the one that will be invoked.
14481
14482
<p>The receiveDrop() method is responsible for carrying out the
14483
effects of dropping the object, including any game-state changes (such
14484
as moving the dropped to its new location) <i>and</i> reporting the
14485
results of the action.
14486
14487
<p>In most cases, the effects won't vary according to which command
14488
was used to discard the object.  This is the reason that there's only
14489
one receiveDrop() method, rather than separate methods for DROP,
14490
THROW, and any library extension or game-specific verbs.  By using a
14491
common routine to handle all means of discarding an object, the game
14492
only has to implement any special handling once.
14493
14494
<p>However, the <i>message</i> will almost always vary according to
14495
the command, for the simple reason that the message needs to
14496
acknowledge what the actor did to discard the item in addition to the
14497
effects of dropping it.  This is the main reason the 'desc' argument
14498
is provided: it's a special "drop descriptor" object that lets you
14499
find out what command was used.  You could also look at gAction to
14500
find the Action being performed, but the descriptor object makes your
14501
job a lot easier by providing some convenience methods for building
14502
report messages.
14503
14504
<p>The descriptor object is of class DropType.  This class has two
14505
important methods.  First, standardReport() displays the "normal"
14506
report for the action.  For DROP, this is simply "Dropped."  For
14507
THROW, this is a message of the form "The ball hits the desk, and
14508
falls to the floor."  You can use the standard report when your
14509
receiveDrop() method doesn't do anything out of the ordinary and thus
14510
doesn't require a special report.  Second, getReportPrefix() returns a
14511
string that gives the <i>start</i> of a sentence describing the
14512
action.  The returned string is a complete main clause for a sentence
14513
-- but it has no ending punctuation, so you can add more to the
14514
sentence if you like.  The main clause will always be written so that
14515
the object being dropped will be the logical antecedent for any
14516
pronouns in subsequent text, which lets you tack on a string like
14517
this: ", and it falls to the floor."
14518
14519
<p>Rather than building a message from the report prefix provided by
14520
the descriptor, you are free to build a completely custom message, if
14521
you prefer.  To do this, you could use 'modify' to add your own method
14522
to each DropType subclass in the library, and then call this method
14523
from your receiveDrop().  Alternatively, you could use ofKind() to
14524
check what kind of DropType descriptor you got, and show custom
14525
messages for the ones you recognize.
14526
14527
</div>
14528
14529
<!------------------->
14530
<div class=entry>
14531
14532
Thing.stopThrowViaPath() now simply calls throwTargetHitWith() by default.
14533
When an object interrupts a projectile's course, the result is exactly as
14534
though the projectile had been successfully thrown at the interrupting
14535
object, so the separate implementations were redundant.
14536
14537
</div>
14538
14539
<!------------------->
14540
<div class=entry>
14541
14542
finishGame() now resets the sense context.  This ensures that if the
14543
event that triggered the end of the game happened while a blocking
14544
sense context was in effect, the finish options are still listed.
14545
(Since the finish options involve direct interaction with the player,
14546
they obviously shouldn't be displayed in any NPC sense context.)
14547
14548
</div>
14549
14550
<!------------------->
14551
<div class=entry>
14552
14553
Thing now has a constructor, which calls initializeThing().  This ensures
14554
that any Thing objects that are created dynamically (with 'new') are
14555
initialized in the same manner as objects defined statically.
14556
14557
</div>
14558
14559
<!------------------->
14560
<div class=entry>
14561
14562
The library's handling of RESTART has been changed slightly to correct
14563
a problem that cropped up under certain unusual circumstances.  The
14564
old handling reset the VM within the Restart action execution method,
14565
and then threw a RestartSignal to tell the main loop to re-enter the
14566
game from the beginning.  This approach had a subtle flaw: if any
14567
dynamically-created objects were referenced from an intermediate stack
14568
frame in the code that initiated the restart, those objects were
14569
retained through the VM reset because they were still accessible via
14570
the stack.  These objects then had a chance to remain visible to an
14571
object loop, such as those that run during the library
14572
pre-initialization.  The Restart action handler now simply throws the
14573
RestartSignal to the main loop, and the main loop now performs the VM
14574
reset.  This ensures that the stack is reset to initial conditions
14575
before the VM reset occurs, which in turn ensures that only those
14576
dynamic objects that should survive the reset do survive the reset.
14577
14578
</div>
14579
14580
<!------------------------------- 3.0.6j --------------------------------->
14581
<div class="sepbar"><a name='306j'></a>3.0.6j</div>
14582
<p><b><i>Released August 2, 2003</i></b>
14583
<p>
14584
14585
<div class=firstentry>
14586
14587
The new class DistanceConnector is a specialized subclass of
14588
SenseConnector that allows two (or more) locations to be connected,
14589
but at a distance.  This is handy for situations such as divided rooms
14590
(where we use two or more Room objects to model a single large
14591
physical location), and for cases where two rooms are open to one
14592
another (such as a balcony overlooking a courtyard).
14593
14594
</div>
14595
14596
<!------------------->
14597
<div class=entry>
14598
14599
The new class Vaporous is a subclass of Intangible designed for
14600
insubstantial but visible objects, such as fire, smoke, and fog.
14601
This class works a lot like Intangible, but it has a visual presence,
14602
and it specifically allows the commands Examine, Smell, and Listen To;
14603
in addition, it allows the commands Look In, Look Under, Look Behind, Look
14604
Through, and Search, and responds to these with "You just see (the
14605
object)."
14606
14607
</div>
14608
14609
<!------------------->
14610
<div class=entry>
14611
14612
The Lister class no longer sets the 'seen' attribute of objects it
14613
lists, because this attribute is now more generally handled in the
14614
main room description routines (per the change in meaning of 'seen'
14615
in 3.0.6i).  As a result, the Lister.markAsSeen method has been
14616
removed.
14617
14618
</div>
14619
14620
<!------------------->
14621
<div class=entry>
14622
14623
A new macro, gSetKnown(obj), marks an object (usually a Thing or a
14624
Topic) as known by the player character.  This is simply short-hand
14625
for obj.setKnownBy(gPlayerChar, true), for convenience.
14626
14627
</div>
14628
14629
<!------------------->
14630
<div class=entry>
14631
14632
The EventList object has been enhanced slightly to accept property
14633
pointer entries.  A property pointer entry is interpreted as a
14634
property to invoke on the EventList itself, with no argument.  This
14635
allows writing complex steps as separate properties of the EventList
14636
object, and then referring to them from the script by property
14637
pointer.
14638
14639
<p>In addition, the ScriptEvent class has been eliminated.  Instead,
14640
simply use Script objects in an event list.  So, when an object
14641
appears in an event list, the EventList class now invokes the
14642
object's doScript() method.  This makes it easy to build event lists
14643
recursively.
14644
14645
<p>The new EventList subclasses CyclicEventList and StopEventList
14646
provide new pre-defined options for the behavior of an event list
14647
after visiting all elements.  The new subclass SyncEventList provides
14648
a list that synchronizes its state with another list.
14649
14650
<p>The TextList, StopTextList, and SyncTextList classes are now
14651
simple subclasses of CyclicEventList, StopEventList, and
14652
SyncEventList, respectively.
14653
14654
<p>A new EventList method, scriptDone(), is invoked by doScript()
14655
after it processes the script's current step.  By default, this
14656
method simply invokes advanceState() to advance the event list to
14657
its next state.  Subclasses can override scriptDone() so that it
14658
does not advance the script's state, or does something else in
14659
addition.
14660
14661
<p>The new EventList subclass ExternalEventList overrides scriptDone()
14662
so that the method does nothing.  This makes it easy to create an
14663
event list that is driven externally; that is, the event list doesn't
14664
advance its state when doScript() is invoked, but only advances its
14665
state in response to some external processing that calls
14666
advanceState() directly on the event list object.
14667
14668
</div>
14669
14670
<!------------------->
14671
<div class=entry>
14672
14673
The Room class now provides a dobjFor(Examine) that replaces the
14674
Examine action with a Look action.  This means that if a Room object
14675
has ordinary vocabulary words defined, and the player types EXAMINE
14676
(room), the command will automatically be treated as though the
14677
player had typed LOOK AROUND.
14678
14679
</div>
14680
14681
<!------------------->
14682
<div class=entry>
14683
14684
The new class IndirectLockable is a subclass of Lockable that
14685
can be used for situations where a lockable object cannot have
14686
its locked status directly manipulated by LOCK and UNLOCK commands.
14687
The reply to LOCK and UNLOCK can be customized via the object's
14688
cannotLockMsg and cannotUnlockMsg properties.
14689
14690
</div>
14691
14692
<!------------------->
14693
<div class=entry>
14694
14695
The Lockable class now handles the 'objUnlocked' precondition a little
14696
more subtly.  The class now keeps track of whether or not the player
14697
knows the object to be locked; the status is assumed to be unknown
14698
initially.  When the player doesn't know the status, the Open action
14699
does <b>not</b> apply an objUnlocked precondition, but instead disallows
14700
the action in the check() routine.  When the status is known, the
14701
objUnlocked precondition is applied as before.  Whenever the Open
14702
action fails in the check() due to the object being locked, the
14703
status is taken to be known for subsequent attempts.
14704
14705
<p>This change makes the precondition handling a little more
14706
intelligent.  When the player doesn't know the status beforehand, an
14707
Open command will simply fail with the discovery that the object is
14708
locked.  This usually makes more sense than attempting to unlock the
14709
object automatically with an implied Unlock command, because if the
14710
object isn't already known to be locked, there's no reason to try to
14711
unlock it.  When the status is known, however, it makes sense to
14712
perform the implied Unlock.
14713
14714
<p>Objects whose lock status is visibly apparent can be marked as such
14715
with the lockStatusObvious property.  This property is nil by default;
14716
an object whose lock status can be visibly observed should set this to
14717
true.  When this property is set, the lock status is <i>always</i>
14718
known, since we'll assume that actors will simply look at the lock and
14719
observe the status.  In addition, when this property is set, we'll add
14720
the locked/unlocked status at the end of the object's 'Examine'
14721
description (we'll add "It's currently locked" or "It's currently
14722
unlocked").
14723
14724
</div>
14725
14726
<!------------------->
14727
<div class=entry>
14728
14729
A new class, TravelWithMessage, can be mixed (using multiple inheritance)
14730
with TravelConnector or a subclass of TravelConnector to create a connector
14731
that shows a message as it's traversed.  This is slightly more flexible
14732
than using TravelMessage, since TravelMessage can't usually be mixed with
14733
other TravelConnector-derived classes.
14734
14735
</div>
14736
14737
<!------------------->
14738
<div class=entry>
14739
14740
A new TravelConnector property, stagingLocation, gives the location
14741
in which a traveler must be located prior to traversing the connector.
14742
In the past, the connector simply assumed the traveler needed
14743
to be in the connector's direct location; this new property allows
14744
this condition to be customized.  At times, the connector might be
14745
inside an intermediate container, for example, in which case the
14746
staging location might be a container of the container.  By default,
14747
the staging location is the connector's location, so connectors that
14748
don't override stagingLocation will have the same behavior as before.
14749
14750
</div>
14751
14752
<!------------------->
14753
<div class=entry>
14754
14755
A new Thing method, roomLocation, returns the 'self' if the object
14756
is capable of serving as a location for actors, or the nearest
14757
container that is a roomLocation otherwise.  
14758
14759
<p>The Passage travel connector class now uses the other side's
14760
container's roomLocation as the default destination of the passage,
14761
rather than the other side's immediate container, as it did in the
14762
past.  This makes it much easier to create passages that model
14763
non-trivial containment relationships, such as holes in walls, since
14764
an intermediate container (between the Passage and the enclosing Room
14765
or NestedRoom) will no longer create any confusion in performing the
14766
travel.
14767
14768
</div>
14769
14770
<!------------------->
14771
<div class=entry>
14772
14773
The NoTravelMessage class can now multiply inherit from Script, for
14774
convenience in defining message lists.  If you want to provide several
14775
different messages to choose from when the connector is traversed, you
14776
can make your connector object inherit from TextList as well as
14777
NoTravelMessage, and the travelDesc() will automatically invoke the
14778
script to show a message.
14779
14780
</div>
14781
14782
<!------------------->
14783
<div class=entry>
14784
14785
<p>If the travel connector has a non-nil location, the TravelConnector
14786
class's connectorTravelPreCond method adds a precondition that the
14787
connector must be touchable.  This ensures that characters won't be
14788
allowed to traverse connectors that are visible but on the other side
14789
of a window, for example, or connectors that are out of reach.
14790
14791
</div>
14792
14793
<!------------------->
14794
<div class=entry>
14795
14796
The travel notification protocol has been changed very slightly.  The
14797
travel connector's noteTraversal() method is now invoked from within
14798
the Traveler.travelerTravelTo() method rather than the TravelVia
14799
handler in the connector.  This change means that noteTraversal()
14800
is called just before the traveler is actually moved, and in particular
14801
that it occurs <i>after</i> all of the other travel notifications
14802
(beforeTravel, actorTravel, and travelerLeaving).  This is generally
14803
the more desirable ordering for the notifications, because it puts
14804
the connector's reaction closest to the actual traveler movement.
14805
If you want the connector to do something special before any of the
14806
other notifications, you can override the action() handler
14807
in the connector's dobjFor(TravelVia) so that it performs the special
14808
code and then inherits the base class handling.
14809
14810
</div>
14811
14812
<!------------------->
14813
<div class=entry>
14814
14815
When an actor travels through a connector that leads to a location
14816
with a posture other than the actor's original posture, the new
14817
location now sets the actor's posture directly, rather than via a
14818
nested action.  For example, if a travel connector leads to a chair,
14819
then traversing the connector will move the actor into the chair and
14820
set the actor's posture to 'sitting', without activating a nested Sit
14821
action.  In the past, the nested Sit action would have been used
14822
instead.  This change is in BasicLocation.travelerArriving(), which
14823
sets the new actor's posture via a call to Actor.makePosture().
14824
14825
<p>This change is generally desirable because we usually want arrival
14826
by travel connector to be self-contained; we don't want it to appear
14827
as though the character walked to the new location and only then
14828
performed a SIT ON THE CHAIR command (say).  It's worth noting,
14829
however, that any side effects of the usual way of getting into the
14830
new location's posture will be skipped.  Therefore, when linking a
14831
travel connector into a nested room with a non-standing posture, you'll
14832
need to consider any side effects you'd want to trigger, and trigger
14833
them explicitly on the travel connector itself.
14834
14835
</div>
14836
14837
<!------------------->
14838
<div class=entry>
14839
14840
The new Actor method scriptedTravelTo() simplifies coding of scripted
14841
travel for an actor.  This routine is suitable for cases where an NPC
14842
is to perform a series of scripted travel actions, where each room
14843
along the way is scripted in advance.  This routine is <i>not</i>
14844
suitable for goal-seeking NPC's, because it can only perform travel to
14845
a location adjacent to the actor's current location, and because it's
14846
"omniscient" (it doesn't take into account the actor's knowledge of
14847
the the map, but simply considers the actual map).  For cases where
14848
an NPC is to visit a scripted series of locations, this is a convenient
14849
way to accomplish the travel, since it requires specifying only the
14850
destination of each step of the travel.
14851
14852
</div>
14853
14854
<!------------------->
14855
<div class=entry>
14856
14857
The class SecretDoor is now based on BasicOpenable as well as
14858
ThroughPassage.  The class previously didn't have BasicOpenable
14859
anywhere among its superclasses, which prevented its open/closed
14860
mechanisms (initiallyOpen, isOpen, makeOpen) from working
14861
consistently with other types of doors, which are all based
14862
(indirectly) on BasicOpenable.
14863
14864
</div>
14865
14866
<!------------------->
14867
<div class=entry>
14868
14869
The new ThroughPassage subclass PathPassage is a specialization for
14870
cases such as outdoor walkways, paths, and streets.  The key
14871
difference between the standard ThroughPassage and the more
14872
specialized PathPassage is that path passages are not considered
14873
enclosed, so the descriptions for arrival and departure via a path
14874
take this into account.  In the English messages, we describe travel
14875
on a path as being "via" the path rather than "through" it.  In
14876
addition, the English parser accepts "take" as a synonym for "enter"
14877
or "go through."
14878
14879
<p>To handle this new class, TravelMessageHandler and its subclasses
14880
have a new pair of methods, sayArrivingViaPath() and
14881
sayDepartingViaPath(), for generating travel messages related to
14882
paths.
14883
14884
14885
</div>
14886
14887
<!------------------->
14888
<div class=entry>
14889
14890
The new method Actor.actorTravel(traveler, connector) complements
14891
beforeTravel() and afterTravel().  This new method is called on the
14892
actor who <b>initiated</b> the travel (that is, the actor performing
14893
the command, if any); it's called after the beforeTravel()
14894
notifications are sent to nearby objects.  This method is provided for
14895
symmetry with the beforeAction/actorAction/afterAction set.
14896
14897
</div>
14898
14899
<!------------------->
14900
<div class=entry>
14901
14902
The AccompanyingState.accompanyTravel() method has been changed slightly.
14903
The first parameter is now a Traveler object, which might be an Actor but
14904
could also be another kind of Traveler, such as a Vehicle.  This allows
14905
the game to determine whether the NPC is to accompany actors when they
14906
travel on vehicles or in other indirect ways.
14907
14908
<p>In addition, the class's beforeAction() method, which responded to
14909
the initiating actor's travel, has been changed to a beforeTravel()
14910
method.  This takes advantage of the more precise kind of notification
14911
offered by beforeTravel().  In particular, using this method avoids
14912
unnecessary attempts to accompany an actor who attempts a travel command
14913
that doesn't actually result in travel (because the connector doesn't
14914
go anywhere, for example).
14915
14916
</div>
14917
14918
<!------------------->
14919
<div class=entry>
14920
14921
If a travel connector is located inside a nested room, the
14922
preconditions for traversing the connector now correctly move the
14923
character to the nested room prior to the travel.  In the previous
14924
library version, the enclosing room tried to add its own precondition
14925
requiring the traveler to be in the outer room, which was incorrect.
14926
14927
</div>
14928
14929
<!------------------->
14930
<div class=entry>
14931
14932
The Follow command now provides better feedback to the player in
14933
certain cases.  When the player has previously observed the target
14934
actor departing, but from a different location than the player's
14935
current location, the Follow command will now respond with the message
14936
"You didn't see which we he went" (rather than "You can't do that from
14937
here" as it did in the past).
14938
14939
</div>
14940
14941
<!------------------->
14942
<div class=entry>
14943
14944
An Actor's executeTurn() method, and all of the methods it invokes
14945
(the Actor's idleTurn() and the ActorState's takeTurn(), for
14946
example), now run within a valid "action environment," just like
14947
fuses and daemons started doing in 3.0.6i.  In addition, the
14948
executeTurn() method sets up a visual sense context for the actor, 
14949
ensuring that any output displayed in the course of the actor's turn
14950
is displayed only when the actor is visible to the player character.
14951
(It is presumed that the effects of any action that an actor performs
14952
are visible if and only if the actor is visible.  This is just the
14953
default case, though: the game is always free to set up a separate
14954
sense context, using callWithSenseContext(), whenever necessary.)
14955
14956
<p>To facilitate this change and make it easier to override an actor's
14957
per-turn processing, the main handling for an actor's turn is now in
14958
a new method, executeActorTurn().  The executeTurn() method simply sets
14959
up the action environment and then invokes executeActorTurn().  In most
14960
cases, subclasses that need to specialize the per-turn processing should
14961
override executeActorTurn() rather than executeTurn(), since this will
14962
let the override run in the action environment.
14963
14964
</div>
14965
14966
<!------------------->
14967
<div class=entry>
14968
14969
The optional initial "look around" that the runGame() function
14970
performs is now executed within an "action environment," just like
14971
fuses and daemons started doing in 3.0.6i.  This allows the initial
14972
room description to refer to gActor and gAction, which some library
14973
methods do implicitly.
14974
14975
</div>
14976
14977
<!------------------->
14978
<div class=entry>
14979
14980
callWithSenseContext() now uses "lazy evaluation": rather than
14981
immediately calculating the effect of the new sense context, the
14982
routine now simply notes that it has a new context, and defers
14983
calculating the effects of the new context until the effects actually
14984
need to be known.  This makes it very inexpensive to set up a new
14985
sense context in cases where the context won't actually be needed for
14986
anything, which is frequently the case in daemons, fuses, and the
14987
standard per-turn processing for NPC's.  This can save a substantial
14988
amount of time when a game has numerous background events if, as is
14989
typical, most of the background events don't generate any output on a
14990
given turn.
14991
14992
</div>
14993
14994
<!------------------->
14995
<div class=entry>
14996
14997
The new macros actorStateDobjFor(action) and actorStateIobjFor(action)
14998
make it convenient to delegate an actor's processing for an action to
14999
the actor's current ActorState object.  These are defined in adv3.h,
15000
and work analogously to asDobjFor(action) and asIobjFor(action).  Using
15001
these macros involves two steps.  First, in the Actor, write a short
15002
handler for the action that uses the macro to delegate to the state
15003
object:
15004
15005
<p><pre>
15006
  bob: Person
15007
    // ... other definitions ...
15008
    dobjFor(AttackWith) actorStateDobjFor(AttackWith)
15009
  ;
15010
</pre>
15011
15012
<p>This sets up the "bob" Actor object so that the handling for
15013
AttackWith, with bob as the direct object, will be delegated to bob's
15014
current ActorState object.  Second, just write a normal dobjFor() handler
15015
in each of the ActorState objects associated with bob:
15016
15017
<p><pre>
15018
  + bobFighting: ActorState
15019
    dobjFor(AttackWith)
15020
    {
15021
      action() { "Bob puts up a fight..."; }
15022
    }
15023
  ;
15024
  + bobCowering: ActorState
15025
    dobjFor(AttackWith)
15026
    {
15027
      action() { "Bob just hides in the corner..."; }
15028
    }
15029
  ;
15030
</pre>
15031
15032
</div>
15033
15034
<!------------------->
15035
<div class=entry>
15036
15037
The withActionEnv() function now takes an addition parameter giving
15038
the Actor object to use as the gActor value while running the
15039
callback.  In the past, this function always used the player character
15040
Actor (given by gPlayerChar); the new parameter allows other actors to
15041
be used instead.
15042
15043
</div>
15044
15045
<!------------------->
15046
<div class=entry>
15047
15048
The withCommandTranscript() function now returns the result of the
15049
callback function, rather than the transcript object created to run
15050
the callback.  Callers who still need the transcript object as the
15051
result can simply return gTranscript from the callback function
15052
itself, as this value will then be passed up as the return value from
15053
withCommandTranscript().
15054
15055
</div>
15056
15057
<!------------------->
15058
<div class=entry>
15059
15060
The attentionSpan property of an InConversationState object can now be
15061
set to nil to indicate that there is no attention span limit for the
15062
NPC.  Setting attentionSpan to nil will prevent the NPC from ever
15063
ending the conversation by virtue of being ignored for too long.
15064
15065
</div>
15066
15067
<!------------------->
15068
<div class=entry>
15069
15070
The standard SpecialTopic template (in adv3.h) now allows defining a
15071
list of strings (for the textStrings property) in place of a single
15072
response.  The standard TopicEntry, SpecialTopic, and YesNoTopic
15073
templates now make the response/response list entry optional, allowing
15074
the rest of the templates to be used even if a custom method is
15075
needed to handle the response.
15076
15077
</div>
15078
15079
<!------------------->
15080
<div class=entry>
15081
15082
A new DefaultTopic subclass, DefaultAnyTopic, matches all of the
15083
different sorts of topic interactions: ASK, TELL, GIVE, and SHOW.
15084
This is especially useful for default handling in conversation nodes
15085
(ConvNodes) where you want catch all topics not otherwise handled.
15086
15087
</div>
15088
15089
<!------------------->
15090
<div class=entry>
15091
15092
The new TopicEntry property isConversational lets a TopicEntry
15093
specify whether or not the response is "conversational."  A
15094
conversational response is one that involves some kind of interaction
15095
with the NPC.  This property is true by default, but some response
15096
objects will want to set it to nil to indicate that the response
15097
doesn't involve any conversation with the NPC.  For example, a
15098
response like "You don't think he wants to discuss that right now" is
15099
non-conversational, because it doesn't involve any exchange with the
15100
NPC.
15101
15102
<p>When isConversational is nil for the response object that's found
15103
for a conversation command, a ConversationReadyState will <b>not</b>
15104
enter its in-conversation, but will simply show the response and
15105
remain in the conversation-ready state.  This means that there will
15106
be no "greeting" exchange for these responses.
15107
15108
</div>
15109
15110
<!------------------->
15111
<div class=entry>
15112
15113
The new ConvNode method canEndConversation(actor, reason) lets a node
15114
prevent a conversation from ending.  'reason' is an enum indicating
15115
what is triggering the attempted termination: endConvBye if the player
15116
typed BYE; endConvTravel if the other actor is leaving (i.e., the player
15117
typed a travel command); or endConvBoredom if we're terminating the
15118
conversation on our own because our attentionSpan has been exceeded.
15119
This method can cancel the operation that attempted the termination
15120
simply by returning nil; the method should display an explanation
15121
when returning nil, to let the player know why the command is being
15122
canceled.
15123
15124
<p>In related changes, ConvNode.endConversation() and
15125
ActorState.endConversation() now take 'reason' codes rather than
15126
'explicit' flags.  This gives the methods full details on why the
15127
termination is occurring.
15128
15129
</div>
15130
15131
<!------------------->
15132
<div class=entry>
15133
15134
The new AgendaItem class provides a simple new mechanism for handling
15135
cases where you want to model an NPC in terms of motivation.  Each
15136
actor has an "agenda," which is a list of AgendaItem objects.  On each
15137
turn, the actor's ActorState object (in the takeTurn method) will look
15138
at the agenda list, to see if any items are ready to execute.  If
15139
there's an item that's ready to execute, the ActorState will execute
15140
the first one that's ready.
15141
15142
<p>Each AgendaItem object has a method called isReady, which indicates
15143
whether or not the item is ready to execute.  An actor will only execute
15144
an agenda item once it's ready.  The invokeItem method contains the code
15145
that actually carries out the agenda item's action.
15146
15147
<p>By default, an agenda item is removed from the actor's agenda list
15148
when it's executed.  However, if the item's stayInList property is true,
15149
then the item will not be removed on execution.  This property lets you
15150
handle agenda items which the actor will try repeatedly, until some
15151
other code determines that the goal has been achieved and removes the
15152
item from the actor's agenda.
15153
15154
<p>You must nest AgendaItem objects within their actor, using the "+"
15155
notation.  This associates the AgendaItem objects with the actor, but
15156
it doesn't add them to the actor's agenda list.  You must explicitly
15157
add agenda items to the actor's agenda list by calling the actor's
15158
addToAgenda() method.  Agenda items must be explicitly added because
15159
an actor's motivation typically will change dynamically as the game's
15160
events unfold.
15161
15162
</div>
15163
15164
<!------------------->
15165
<div class=entry>
15166
15167
Autonomous NPC conversation continuation processing has been moved
15168
from InConversationState to the base ActorState.  This allows actors
15169
that don't use greeting protocols to nonetheless use stateful
15170
conversations.
15171
15172
<p>To accommodate this change, the default takeTurn() method in
15173
ActorState now preforms more processing.  If the actor has an active
15174
ConvNode, then this takes precedence over any other default processing
15175
for the actor's takeTurn() method.  If the actor hasn't engaged in
15176
conversation on the same turn, we invoke the ConvNode to continue the
15177
conversation under NPC control; otherwise, we do nothing more.  If
15178
there's no ConvNode, we process the actor's "agenda."  If there's no
15179
ConvNode, and the actor has no agenda items that are ready to execute,
15180
and the ActorState inherits from Script, then we invoke the script.
15181
This structure means that a stateful conversation takes precedence
15182
over everything, and an agenda item takes precedence over state-level
15183
background activity.
15184
15185
</div>
15186
15187
<!------------------->
15188
<div class=entry>
15189
15190
In the Actor class, the TellAbout and AskAbout handlers now include
15191
the "canTalkToObj" precondition by default.  This ensures that the NPC
15192
being addressed can actually hear the other actor, to disallow
15193
conversations in cases such as when the two actors are too far apart
15194
to hear one another.  The HELLO, GOODBYE, YES, and NO commands now all
15195
make the same check as well, in the sayToActor() method.
15196
15197
<p>Similarly, ConversationReadyState now makes the same check before
15198
going through a greeting.  If the initating actor can't talk to the
15199
target actor, the enterConversation() method says so and uses 'exit'
15200
to terminate the command.  This prevents strange situations from
15201
arising commands that don't require the canTalkToObj precondition.
15202
(SHOW TO works this way, because the actors don't necessarily have to
15203
be able to talk to each other to use SHOW TO; we could show a note to
15204
an NPC on the other side of a sound-proof window, for example.)
15205
15206
</div>
15207
15208
<!------------------->
15209
<div class=entry>
15210
15211
The new TopicEntry subclass InitiateTopic provides an easy way of
15212
making an NPC initiate conversation based on simulation objects in the
15213
environment.  To make an NPC trigger a conversation, call the actor's
15214
initiateTopic(obj) method, where 'obj' is the simulation object you
15215
want to use to key the conversation.  This will find an InitiateTopic
15216
object in the actor's topic database matching the given object
15217
('obj'), and show its response text.  One easy way to use this is to
15218
initiate conversation based on the NPC's current location: just create
15219
InitiateTopic objects keyed to those locations where you want the NPC
15220
to say something special, and add a line like this to the ActorState's
15221
takeTurn() method:
15222
15223
<p><pre>
15224
  getActor().initiateTopic(getActor().location);
15225
</pre>
15226
15227
</div>
15228
15229
<!------------------->
15230
<div class=entry>
15231
15232
The "topic inventory" list shown by the TOPICS command is no longer
15233
enclosed in parentheses by default.  The parentheses are still included
15234
when the topic inventory is shown implicitly (by a TALK TO command or
15235
a &lt;.topics&gt; tag, for example).
15236
15237
</div>
15238
15239
<!------------------->
15240
<div class=entry>
15241
15242
The new ConvNode property limitSuggestions allows a ConvNode to
15243
indicate that suggested topics from the broader conversation context
15244
should not be included in a topic inventory listing.  This is useful
15245
for times when the ConvNode won't allow the player to stray from the
15246
subject, such a a ConvNode that only allows a YES or NO answer to a
15247
question.  In these cases, set limitSuggestions to true.  The property
15248
is nil by default, which causes topic inventory listings to include
15249
not only any suggestions defined within the ConvNode, but also any
15250
defined in the active ActorState or in the Actor itself.
15251
15252
</div>
15253
15254
<!------------------->
15255
<div class=entry>
15256
15257
The new Actor.scheduleInitiateConversation(state, node, turns) method 
15258
lets the game set up an NPC to start a converation at the next opportunity
15259
after the given number of turns has elapsed.  If 'turns' is zero, then
15260
the conversation can start on the next turn on which the NPC hasn't
15261
been targeted for conversation by the player; if 'turns' is one, the
15262
player will get at least one more turn before the conversation can start,
15263
and so on for higher 'turns' values.  The important thing is that the
15264
conversation can only start on a turn on which the NPC isn't targeted
15265
with a conversational command (ASK, TELL, etc).  The Actor checks its
15266
list of pending conversations on each turn in its takeTurn() method,
15267
before invoking the current state's takeTurn() method.
15268
15269
</div>
15270
15271
<!------------------->
15272
<div class=entry>
15273
15274
In the previous version, if Actor.initiateConversation() was called
15275
from within the player character's turn (in an NPC's beforeAction()
15276
handler responding to a player character action, for example), and
15277
the ConvNode had a "continuation" message (defined in
15278
npcContinuationMsg or npcContinuationList), the first continuation
15279
message was incorrectly shown on the same turn.  This no longer
15280
occurs; the continuation message won't be shown until the next turn
15281
at the earliest.  ("At the earliest," because a continuation message
15282
won't be shown on a given turn if the player character addresses a
15283
conversational command to the NPC on that turn.)
15284
15285
</div>
15286
15287
<!------------------->
15288
<div class=entry>
15289
15290
When an actor continues a conversation of its own volition (using
15291
npcContinueMsg or npcContinueList) in a ConvNode, if the continuation
15292
routine actually displays any text, then the ConvNode will
15293
automatically set the player character and the initiating NPC to be in
15294
conversation with one another.  This ensures that any subsequent
15295
conversational command from the player will have the initiating NPC as
15296
the default interlocutor.
15297
15298
</div>
15299
15300
<!------------------->
15301
<div class=entry>
15302
15303
In the past, the REPLAY QUIET command didn't display any acknowledgment,
15304
and improperly left all subsequent text in bold-face.  This has been
15305
corrected.
15306
15307
</div>
15308
15309
<!------------------->
15310
<div class=entry>
15311
15312
ActorState.greetingsFrom now delegates to a method of the same name
15313
in Actor; this makes it easier to change the default greeting for a
15314
simple actor without a state object.
15315
15316
<p>Along the same lines, ActorState.showGreetingMsg has been removed,
15317
and replaced with Actor.defaultGreetingResponse.  The method has been
15318
moved to Actor because of the change to greetingsFrom, and the method
15319
has been renamed for consistency with the similar pattern for the
15320
other conversation command default message methods (for ASK, TELL,
15321
etc) in Actor.
15322
15323
<p>Along the same lines, ActorState.goodbyeFrom now delegates to a
15324
method of the same name in Actor by default.  A new Actor method,
15325
defaultGoodbyeResponse, displays the default message, for consistency
15326
with the naming of the similar methods for other conversation
15327
commands.
15328
15329
</div>
15330
15331
<!------------------->
15332
<div class=entry>
15333
15334
Two new ConversationReadyState methods have been added:
15335
enterFromByeMsg and enterFromConvMsg.  These are provided for
15336
convenience as single-message complements for enterFromByeList and
15337
enterFromConvList, respectively.  By default, these simply invoke
15338
their respective list scripts.
15339
15340
</div>
15341
15342
<!------------------->
15343
<div class=entry>
15344
15345
VocabObject has a new feature that allows an object's vocabulary to
15346
be divided into "strong" and "weak" tokens.  Weak and strong tokens are
15347
the same as far as the parser is concerned, and are entered into the
15348
dictionary as usual.  The difference is that a weak token can only
15349
be used to refer to an object in combination with one or more strong
15350
tokens.  That is, if the player enters a noun phrase, and the noun
15351
phrase matches all of the vocabulary for a given in-scope object,
15352
the object will match the noun phrase only if one or more of the
15353
words in the noun phrase is a strong token for the object.
15354
15355
<p>The purpose of this new feature is to make it easy to define extra
15356
vocabulary for an object that the parser accepts for an object
15357
without creating any new ambiguity.  This comes up in situations
15358
where you simply want to create additional synonyms for an object, as
15359
well as in cases where an object is most strongly identified in terms
15360
of its relationship to something else.  For example, you might have a
15361
location that contains a couple of doors, one to a house and the
15362
other to a shed.  You could use adjectives ("house door" and "shed
15363
door") to differentiate the doors, but it might be more natural to
15364
use a prepositional phrasing, such as "the door of the house" and
15365
"the door of the shed."  If you also have a house and a shed object,
15366
though, this phrasing would create unwanted ambiguity with those
15367
objects.  This is where weak tokens come in.  If you define "house"
15368
and "shed" as weak tokens for the respective door objects, the parser
15369
will never take those words alone to refer to the doors, so there
15370
will be no ambiguity with the house and shed objects themselves; but
15371
the parser will still allow "house" and "shed" to refer to the doors,
15372
as long as they're used in combination with the strong token "door".
15373
15374
<p>Weak tokens are defined per-object (they're not global).  Each
15375
object that has weak tokens keeps a list of its weak tokens in its
15376
'weakTokens' property.  In the basic VocabObject.matchName()
15377
implementation, the object checks the noun phrase to see if it
15378
consists entirely of weak tokens, and rejects the match if so.
15379
15380
<p>When you define an object, you can define weak tokens in one
15381
of two ways.  If you define 'noun' and 'adjective' (etc.) properties
15382
directly, simply define a 'weakTokens' property containing a list of
15383
strings giving the object's weak tokens.  If you use the
15384
vocabulary initialization string, simply enclose each weak token
15385
in parentheses.  For example:
15386
15387
<p><pre>+ Door 'front door/(house)' 'front door of house' 
15388
  "The door is badly weathered. "
15389
;
15390
</pre>
15391
15392
</div>
15393
15394
<!------------------->
15395
<div class=entry>
15396
15397
VocabObject.matchName() and matchNameDisambig() now invoke a new
15398
method, matchNameCommon(), to carry out their common handling.
15399
This change facilitates the weak-token feature mentioned above.
15400
In most cases, when a game needs to override an object's name
15401
matching test, it should override matchNameCommon(), since this
15402
method provides the common handling for normal matching and
15403
disambiguation matching.  Games can still override matchName()
15404
and/or matchNameDisambig() individually, but it's only necessary
15405
to do so when you want to use different rules for normal matching
15406
and disambiguation matching.
15407
15408
</div>
15409
15410
<!------------------->
15411
<div class=entry>
15412
15413
The English parser's handling of quoted string literals as adjectives
15414
has been improved slightly, but the changes will require some small
15415
adjustments to any games currently using literal adjectives.
15416
15417
<p>Instead of allowing any adjective to be quoted, the parser now
15418
only matches quoted strings that are specifically designated as
15419
"literal adjectives" in an object's vocabulary.  To designate an
15420
adjective as a literal adjective, you can either enclose the
15421
adjective in double-quotes in the vocabulary initializer string, or
15422
you can explicitly define the word using the 'literalAdjective'
15423
part-of-speech property instead of the normal 'adjective'
15424
part-of-speech.  For example, you could define an elevator button
15425
for the lobby level like so:
15426
15427
<p><pre>+ Button '"L" button' 'L button' "It's a button labeled &lt;q&gt;L.&lt;/q&gt; ";
15428
</pre>
15429
15430
<p>This change makes the parser stricter about which words it accepts
15431
as quoted adjectives, but it also allows the parser to be more
15432
flexible about requiring the quotes.  In particular, the parser now
15433
accepts all of the following forms for the button defined above: "L"
15434
button, button "L", L button, and button L.  In the past, the parser
15435
was unable to accept the last of these, because without the quotes,
15436
it wasn't able to tell that the unquoted "L" was meant as a literal
15437
adjective.  Now that the "L" is defined in the dictionary as a
15438
literal adjective, it's no longer necessary for the player to quote
15439
the word for the parser to recognize it as a literal adjective, so
15440
the parser is able to accept the form with the literal adjective
15441
following the noun.
15442
15443
<p>Note that this change also involves a subtle change to the special "*"
15444
vocabulary wildcard token.  In the past, if the string '"*"' (that is,
15445
an asterisk enclosed in double-quotes) appeared as an 'adjective' 
15446
dictionary entry for an object, then that object matched any quoted
15447
string used as an adjective in player input.  Now, this effect is
15448
obtained by using the string '*' as a 'literalAdjective' dictionary
15449
entry for an object.  This change has no effect at all on the way you
15450
write vocabulary initializer strings, since you still enclose the
15451
asterisk in quotes in that string; however, if you're defining a
15452
'literalAdjective' list directly for an object, you now must drop
15453
the quotes and add a word entry consisting of simply the asterisk.
15454
15455
</div>
15456
15457
<!------------------->
15458
<div class=entry>
15459
15460
The English parser now accepts pronouns as responses to
15461
disambiguation questions.  (The disambigListItem(noun) rule now
15462
matches completeNounPhraseWithoutAll rather than qualifiedNounPhrase,
15463
as it did in the past; the new sub-production matches pronouns, which
15464
qualifiedNounPhrase does not.)
15465
15466
</div>
15467
15468
<!------------------->
15469
<div class=entry>
15470
15471
In the English parser rules, the command "T <i>topic</i>" is now
15472
accepted as a short-cut for "TELL ABOUT <i>topic</i>."  Together with
15473
the "A <i>topic</i>" shortcut for ASK ABOUT, this can greatly reduce
15474
the amount of typing a player has to do in a game that has a lot of
15475
ASK/TELL character interaction.
15476
15477
</div>
15478
15479
<!------------------->
15480
<div class=entry>
15481
15482
In the English parser rules, the Hello action now accepts "hallo"
15483
as equivalent to "hello" or "hi", and also accepts "say" with any
15484
of these variations.
15485
15486
</div>
15487
15488
<!------------------->
15489
<div class=entry>
15490
15491
A new Action method, callAfterActionMain(obj), allows a game to register
15492
an object for invocation at the end of the current action.  This is
15493
only meanginful when used on the current gAction object, since it
15494
registers for notification of completion of the current action.
15495
When the current action is finished - including the iteration over
15496
all of the objects involved in the action - the action invokes
15497
the afterActionMain() method of each registered object.
15498
15499
<p>This new method is especially useful for adding a "summary" of an
15500
action that involves multiple objects.  Each individual object's
15501
action handler (an action() method in a dobjFor() block, for example)
15502
can register a handler object to receive notification when the
15503
overall command is finished.  A given object can be registered only
15504
once - redundant registrations are simply ignored - so each
15505
individual iterated object doesn't have to worry about whether or not
15506
other iterated objects will register the same handler.  Then, at the
15507
end of the action, the handler will be invoked; it can determine what
15508
happened in the action, and do something based on the end result.
15509
For example, the handler could scan the transcript (gTranscript) for
15510
certain types of reports, and add a summary message based on the
15511
reports, or could even replace some of the individual reports with a
15512
summary.  The handler could also take addition action based on the
15513
overall end results; for example, in a GIVE TO command, a handler
15514
could look at the full set of objects successfully given, and decide
15515
that the combination is sufficient to allow the recipient to give the
15516
donor something in return.
15517
15518
</div>
15519
15520
<!------------------->
15521
<div class=entry>
15522
15523
A new CommandTranscript method, summarizeAction(), can be used with
15524
the new callAfterActionMain() system to generate a summary of an
15525
action that involves multiple objects.  summarizeAction() scans
15526
through the transcript, looking for runs of two or more reports for
15527
the current action that match criteria specified by the caller (via a
15528
callback function).  For each run of two or more consecutive
15529
qualifying reports, the method removes those reports, along with their
15530
corresponding multi-object announcements, and replaces the last of the
15531
reports with a single "summary" report generated by the caller (via
15532
another callback function).  This method lets you turn a transcript
15533
like this:
15534
15535
<p><pre>   gold coin: Bob accepts the gold coin.
15536
   gold coin: Bob accepts the gold coin.
15537
   gold coin: Bob accepts the gold coin.
15538
</pre>
15539
15540
<p>into something like this:
15541
15542
<p><pre>   Bob accepts the three gold coins.
15543
</pre>
15544
15545
<p>This sort of summary isn't straightforward to generate in general,
15546
and the library makes no attempt to apply it generically.  In specific
15547
cases where you can control the range of possible results, though,
15548
this can be a powerful way to improve the game's output by describing
15549
an iterated action as though it were a single logical unit.
15550
15551
</div>
15552
15553
<!------------------->
15554
<div class=entry>
15555
15556
Phrases involving quantities ("five coins") and "all" with a plural
15557
("all coins") are now resolved a little more consistently and
15558
intuitively, from a player's perspective.  First, phrases involving
15559
quantities are now always disambiguated in the same manner as
15560
singular phrases, and then the required number of objects is chosen;
15561
in the past, disambiguation filtering was not as consistent.  This
15562
change ensures in particular that "collectives" are properly filtered
15563
in or out; the old mechanism sometimes missed collectives because it
15564
sometimes skipped the normal disambiguation filtering.  Second,
15565
"all"-plus-plural phrases are now resolved to all matching objects,
15566
rather than to only the most logical subset of matching objects, as
15567
was the case in the past.  This means that a command applied to "all
15568
coins" really is applied to all coins that are present, even those
15569
for which the action isn't currently valid.
15570
15571
<p>To implement these changes, NounPhraseProd has a new method,
15572
getVerifyKeepers(), that the disambiguation filtering methods call to
15573
reduce the list.  The default NounPhraseProd definition of the method
15574
does the traditional filtering that the disambiguation filter did,
15575
which keeps just the most logical subset of the results.
15576
AllPluralProd overrides this method to keep everything in the list,
15577
and QuantifiedPluralProd overrides the method to select a subset with
15578
the desired number of entries.
15579
15580
</div>
15581
15582
<!------------------->
15583
<div class=entry>
15584
15585
<p>The CollectiveGroup object by default no longer matches a noun
15586
phrase that specifies a quantity ("take five coins" or "take both
15587
coins"; or any singular phrase, since a singular phrase specifies a
15588
quantity of one).  Collective groups are designed to stand in for
15589
a completely collection of in-scope individuals, not for arbitrary
15590
subsets of the individuals, so when a quantity is specified we must
15591
fall back on iterating over a selected subset of the individuals.
15592
15593
<p>To implement this change, the filterResolveList() method now takes
15594
two additional parameters: one giving the quantity specified in the
15595
noun phrase, if any, and another giving the role played by the object
15596
(DirectObject, IndirectObject, etc).  When the noun phrase specifies
15597
a quantity, the new parameter will be set to an integer giving the
15598
quantity specified.  If the noun phrase is unspecific about the
15599
quantity (as in "take coins" or "get all coins"), then the quantity
15600
parameter will be nil.  
15601
15602
<p>Note that the isCollectiveAction() method now takes an additional
15603
parameter as well, giving the role in the action played by the object
15604
being resolved (DirectObject, IndirectObject, etc).  This allows
15605
differentiating the handling based on both the action and the role
15606
played in the action.
15607
15608
<p>Custom CollectiveGroup objects <i>can</i> represent specific
15609
quantities of objects, from the player's perspective, if desired.  For
15610
example, a game might want to create a CollectiveGroup that represents
15611
a quantity of money, rather than dealing with the individual coins
15612
making up the quantity.  To do this, the CollectiveGroup object must
15613
override the filterResolveList() method, and must set the "quant_"
15614
element of its own ResolveInfo entry to an integer giving the number
15615
of <i>grammatical</i> objects it represents.  The CollectiveGroup must
15616
keep track of what it's representing somehow; the best way to do this
15617
is to create a new instance of the CollectiveGroup itself, and store a
15618
property in the new instance giving the quantity represented by the
15619
collective.  Note that using CollectiveGroup objects in this manner
15620
is tricky; you'll need to code action handlers for the custom
15621
CollectiveGroup object so that they correctly take into the account
15622
the quantity represented by the group object.
15623
15624
</div>
15625
15626
<!------------------->
15627
<div class=entry>
15628
15629
The ownershipAndLocationDistinguisher has been refactored into two
15630
separate distinguishers: ownershipDistinguisher and locationDistinguisher.
15631
Each of these new distinguishers is very similar to the old combined
15632
distinguisher, but the ownershipDistinguisher gives priority to 
15633
ownership, regardless of the containment relationship.  The library
15634
classes that define distinguishers now use both of these, with
15635
the ownership distinguisher applied first.
15636
15637
<p>The purpose of this change is to ensure that ownership will be
15638
used as a distinguishing feature whenever possible, before the parser
15639
falls back on location.  The old combined distinguisher could only
15640
use ownership in the limited case where the owner and immediate
15641
location were the same, because it couldn't otherwise be sure that it
15642
would be able to distinguish multiple objects with the same owner but
15643
different locations.  By separating the ownership and location
15644
distinguishers, we first try to identify objects purely by ownership;
15645
when this fails, we fall back on the old approach of identifying by
15646
immediate location in preference to owner.
15647
15648
<p>To support this change, the English methods for owner-or-location
15649
names (aNameOwnerLoc, theNameOwnerLoc, countNameOwnerLoc) now take
15650
a parameter indicating whether to use ownership or location as the
15651
first priority in generating the name.  When ownership takes priority,
15652
these methods will show the name with a possessive form of the owner
15653
regardless of the containment relationship between the object and its
15654
owner.
15655
15656
</div>
15657
15658
<!------------------->
15659
<div class=entry>
15660
15661
Possessive qualifiers (such as "bob's" in "bob's chair") are now
15662
resolved in a special resolution context that allows referring to
15663
owners that aren't in scope for the purposes of the phrase being
15664
qualified (such as the "chair" in "bob's chair").  A possessive
15665
phrase is now considered in scope if it's in scope for the phrase
15666
being qualified <b>or</b> it's known to the actor performing the
15667
command.  This allows possessive phrases to be used to refer to
15668
objects that are present, and which are known to belong to an
15669
actor, even if the actor itself isn't present.
15670
15671
</div>
15672
15673
<!------------------->
15674
<div class=entry>
15675
15676
When the parser generates a disambiguation prompt, and the prompt
15677
distinguishes objects by possessives ("which match: bob's match or
15678
your match?"), the parser automatically sets the pronoun antecedents
15679
for "him" and/or "her" to the people mentioned in the prompt.  This
15680
allows the player to answer with "his" or "hers" (or "his match"),
15681
referring back to the person or people mentioned in the message.
15682
15683
</div>
15684
15685
<!------------------->
15686
<div class=entry>
15687
15688
The parser error messages that display literal text entered by the
15689
player (such as the message for unrecognized punctuation marks, and
15690
the message for unknown words) now HTML-ify the user's text.  This
15691
ensures that any markup-significant characters (such as "&lt;" and
15692
"&amp;") are converted into HTML sequences that display the
15693
corresponding characters.
15694
15695
</div>
15696
15697
<!------------------->
15698
<div class=entry>
15699
15700
A bug in the English parser's rule for phrases like "anything in the box"
15701
caused run-time errors when the word "anything" alone was used as a noun
15702
phrase.  This has been fixed.
15703
15704
</div>
15705
15706
<!------------------->
15707
<div class=entry>
15708
15709
In the hint system, the new Goal methods openWhenTrue and closeWhenTrue
15710
can be used to define arbitrary conditions that open and close the goal.
15711
These new general-purpose conditions supplement the more specific
15712
conditions (openWhenSeen, openWhenAchieved, etc.); the goal will be
15713
opened if <i>any</i> of the openWhenXxx conditions are met, and will
15714
be closed when any of the closeWhenXxx conditions are met.
15715
15716
<p>The new Goal property openWhenDescribed lets you specify that the goal
15717
should be opened when the referenced object is described (usually with
15718
EXAMINE).  This is good for goals where the existence of a puzzle isn't
15719
made apparent until the full description of an object is viewed.  The
15720
new property closeWhenDescribed correspondingly closes the goal when
15721
the referenced object is described.
15722
15723
</div>
15724
15725
<!------------------->
15726
<div class=entry>
15727
15728
The RESTART command no longer resets the commandSequencer to the
15729
"no-command" state, as it did in the past.  This change corresponds to
15730
the change in commandSequencer start-up state effected in 3.0.6i.
15731
15732
</div>
15733
15734
<!------------------->
15735
<div class=entry>
15736
15737
The English grammar now accepts '1' as a synonym for 'one' or 'any' in
15738
singular indefinite noun phrases, such as "take 1 coin."  (In the
15739
past, the grammar omitted this alternative.)
15740
15741
</div>
15742
15743
<!------------------->
15744
<div class=entry>
15745
15746
The new class SecretFixture is designed for objects that are needed in
15747
the internal implementation but are not meant to be manipulated
15748
directly by characters.  This is a simple subclass of Fixture; the
15749
main difference is that a SecretFixture is hidden from "all," to help
15750
prevent direct references to it in commands.
15751
15752
</div>
15753
15754
<!------------------->
15755
<div class=entry>
15756
15757
In the English grammar, a new production named singleNounOnly can be used
15758
where a single noun (rather than a list of nouns) is <i>structurally</i>
15759
required.  The singleNoun production itself will structurally match a
15760
list of nouns, but considers such matches semantically invalid.  In
15761
contrast, singleNounOnly won't even structurally match a noun list.
15762
15763
<p>The firstCommandPhrase(withActor) rule now uses the new singleNounOnly
15764
production to match the actor phrase.  This eliminates the structural
15765
ambiguity of certain types of invalid input that were able to cause
15766
unbounded memory consumption with the old rule.
15767
15768
</div>
15769
15770
<!------------------->
15771
<div class=entry>
15772
15773
The menu system no longer shows a border in full-screen menu windows.
15774
(When a menu takes up the whole game window, a border is superfluous,
15775
since there's no other window requiring separation.  Removing the
15776
border slightly but noticeably improves the appearance of a full-screen
15777
menu.)
15778
15779
</div>
15780
15781
<!------------------->
15782
<div class=entry>
15783
15784
The Decoration class now gives Examine commands a reduced "logical
15785
rank" (of 70) for disambiguation purposes.  This means that if the
15786
player enters an Examine command, and the vocabulary for the direct
15787
object matches a Decoration object and a non-Decoration object, the
15788
non-Decoration object will be chosen ahead of the Decoration.  It's
15789
usually desirable to treat Decoration objects as second-class citizens
15790
for disambiguation purposes, because they're usually meant to stay in
15791
the background as much as possible.
15792
15793
</div>
15794
15795
<!------------------->
15796
<div class=entry>
15797
15798
The standard Actor handlers for the Give and Show actions now produce
15799
more sensible messages for giving or showing something to oneself.
15800
(The old message was the generic "you do not respond"; the new message
15801
is "Giving [or showing] that to yourself won't accomplish anything.")
15802
15803
</div>
15804
15805
<!------------------->
15806
<div class=entry>
15807
15808
The base definition of the method filterResolveList() has been moved
15809
from Thing to VocabObject.  The parser calls this method on objects
15810
that match vocabulary in player input, so it more properly pertains to
15811
VocabObject than to Thing.  (In practice, this is important in some
15812
cases when Topic objects match player input, because Topic objects
15813
descend from VocabObject but not from Thing.)
15814
15815
</div>
15816
15817
<!------------------->
15818
<div class=entry>
15819
15820
The cached scope list in Resolver and its subclasses is now better
15821
encapsulated, to make it easier to subclass Resolver.  In particular,
15822
the "scope_" member is referenced only in the method cacheScopeList(),
15823
objInScope(), and the new method getScopeList().  This means that a
15824
subclass can dispense entirely with the cached scope list (and the
15825
"scope_" member), as long as the subclass implements objInScope() and
15826
getScopeList() to return mutually consistent results.  A subclass
15827
can alternatively override cacheScopeList() to use a different set
15828
of rules to obtain and cache the scope list.
15829
15830
<p>Along similar lines, TAction.initResolver() now calls
15831
cacheScopeList() to initialize its cached scope list, rather than
15832
doing so directly.  This allows TAction subclasses to customize the
15833
scope rules in exactly the same way that subclasses of Resolver can
15834
customize scope.  Likewise, TopicResolver.filterAmbiguousNounPhrase()
15835
now calls objInScope() rather than accessing the "scope_" list
15836
directly.
15837
15838
</div>
15839
15840
<!------------------->
15841
<div class=entry>
15842
15843
The new Achievement method addToScoreOnce() makes it a little easier
15844
to do score book-keeping in the common case of achievements that are
15845
scorable only once.  This method adds the achievement to the score,
15846
with a given number of points, but only if the achievement has never
15847
been scored before; if the achievement has been scored before, the
15848
method does nothing at all.  This makes it unnecessary to keep track
15849
of any separate status to avoid scoring the same action more than
15850
once.  (Some achievements are meant to be repeatable; this method
15851
wouldn't be useful in such cases, obviously.)
15852
15853
</div>
15854
15855
<!------------------->
15856
<div class=entry>
15857
15858
The complexMultiTransform report transformer is now a little more
15859
liberal in determining when to add visual separation between reports
15860
when an action is iterated over multiple objects.  In the past, visual
15861
separation (i.e., a paragraph break) was added only when implicit
15862
command announcements were present.  Now, visual separation will be
15863
added any time the report group for an individual object in the
15864
iteration consists of more than one report, or a report has a single
15865
message with text over 60 characters in length.  This new, more
15866
liberal policy is designed to add visual separation essentially any
15867
time an individual object's result message is non-trivial, since
15868
multi-object messages become hard to read when they're all jammed
15869
together, unless each individual message is very short.  The new
15870
policy errs on the side of adding too much visual separation, which on
15871
balance seems to do considerably less harm to readability than too
15872
little separation.
15873
15874
</div>
15875
15876
<!------------------->
15877
<div class=entry>
15878
15879
The handling of OOPS responses has been improved slightly.  In
15880
particular, when the player uses an OOPS command to correct an error,
15881
the new text that results from applying the OOPS substitution is now
15882
run through the normal pre-parsing sequence.
15883
15884
<p>In the past, an OOPS command itself was run through the normal
15885
pre-parsing steps, but the new command resulting from applying the
15886
OOPS replacement text was <i>not</i> pre-parsed.  This resulted in
15887
incorrect behavior in certain certain rare cases.  One noticeable
15888
example was when a SpecialTopic was active.  Because SpecialTopics
15889
rely on pre-parsing to match their special command templates, and
15890
because the corrected text after the OOPS wasn't pre-parsed, it was
15891
effectively impossible to use OOPS to correct a typo in a command
15892
intended to match a SpecialTopic.  The new OOPS handling ensures that
15893
pre-parsing is run as normal on the new command resulting from
15894
applying an OOPS correction.
15895
15896
</div>
15897
15898
<!------------------->
15899
<div class=entry>
15900
15901
When the player enters a command that matches an active SpecialTopic,
15902
the library now treats this as a conversational action directed to the
15903
interlocutor, as though the player had typed an ASK or TELL command.
15904
This is important in cases where the actor has background actions that
15905
it performs based on the absence of an explicit conversational
15906
interaction from the player on any given turn, such as showing
15907
ConvNode continuation messages.
15908
15909
</div>
15910
15911
<!------------------->
15912
<div class=entry>
15913
15914
ASK FOR commands are now handled uniformly with other conversational
15915
commands (ASK ABOUT, TELL ABOUT, GIVE TO, etc).  In particular, these
15916
commands are now routed to the ActorState for handling, and can be
15917
handled using the new AskForTopic class, which works along the same
15918
lines as GiveToTopic and ShowToTopic.
15919
15920
</div>
15921
15922
<!------------------->
15923
<div class=entry>
15924
15925
The library now automatically sets the antecedent for the appropriate
15926
pronouns to refer to a responding actor, any time a TopicEntry is used
15927
to generate response text.  This ensures that the player can use a
15928
pronoun on the next command to refer to the last actor who generated a
15929
conversational message.
15930
15931
</div>
15932
15933
<!------------------->
15934
<div class=entry>
15935
15936
The new method Actor.setPronounObj(obj) makes it easier to set a
15937
simulation object as the pronoun antecedent for commands targeting the
15938
given actor.  (In the past, only the setPronoun() method was
15939
available, which took a list of ResolveInfo objects.  When the game or
15940
the library needs to set the pronoun directly, it's often easier to
15941
set it directly in terms of simulation objects, without creating a
15942
ResolveInfo list.)
15943
15944
</div>
15945
15946
<!------------------->
15947
<div class=entry>
15948
15949
The new classes SimpleNoise and SimpleOdor make it easier to define
15950
Noise and Odor objects for the common case that a noise/odor is just
15951
a background part of the room description that (1) doesn't require
15952
ongoing "daemon" announcements, and (2) doesn't need any
15953
differentiation among the different types of descriptive messages.
15954
These classes simply use the "desc" property as the default for all
15955
of the descriptive messages, and are marked as "ambient," to avoid
15956
automatic inclusion in the room description.
15957
15958
</div>
15959
15960
<!------------------->
15961
<div class=entry>
15962
15963
The Throw command now works properly when throwing something at
15964
oneself.  (In the past, throwing something at oneself incorrectly
15965
tried to treat the actor as the drop location of the throw; it now
15966
correctly treats the actor's location as the drop location.)
15967
15968
</div>
15969
15970
<!------------------->
15971
<div class=entry>
15972
15973
The new NOTE verb accepts an arbitrary literal as its object; the
15974
command doesn't do anything except acknowledge the input.  The purpose
15975
of the command is to allow the player to enter arbitrary notes into
15976
the session transcript as she plays the game.  Players might want to
15977
make such notes for their own later reference, but this command is
15978
especially useful for play-testing, because it gives play-testers
15979
a very easy way of pointing out bugs or making comments directly in
15980
the session transcript where they apply, and at the moment they occur
15981
to the player.
15982
15983
</div>
15984
15985
<!------------------->
15986
<div class=entry>
15987
15988
A library bug caused a run-time error if an attempt was made to remap
15989
from a direct object handler (a dobjFor) to an intransitive action
15990
(an action with no objects).  Remapping to intransitive actions will
15991
now work properly.
15992
15993
</div>
15994
15995
<!------------------->
15996
<div class=entry>
15997
15998
The RealTimeDaemon class had a couple of problems that prevented it
15999
from working properly.  For one thing, it wasn't based on RealTimeEvent
16000
as it should have been; for another, it didn't reset its next firing
16001
time when fired.  These problems have been corrected.
16002
16003
</div>
16004
16005
<!------------------------------- 3.0.6i --------------------------------->
16006
<div class="sepbar"><a name='306i'></a>3.0.6i</div>
16007
<p><b><i>Released June 15, 2003</i></b>
16008
<p>
16009
16010
<div class=firstentry>
16011
16012
The commandSequencer now starts in "before-command" mode, rather than
16013
in "no-command" mode.  This allows any introductory text displayed
16014
before the first command to use the normal command sequencing tags.
16015
16016
</div>
16017
16018
<!------------------->
16019
<div class=entry>
16020
16021
The "seen" property of Thing has been changed slightly in meaning.  In
16022
the past, this property was set to true only when an object was
16023
specifically listed as a portable item in a room description.  Now,
16024
the property is set to true whenever a room description is displayed
16025
from the player character's perspective, and the object is visible to
16026
the player character.  The important difference is that
16027
<b>unlisted</b> items, such as 'Fixture' and 'Heavy' items, or items
16028
with special descriptions, will be marked as seen as soon as their
16029
containing rooms are described.
16030
16031
</div>
16032
16033
<!------------------->
16034
<div class=entry>
16035
16036
Due to a bug in the previous version, the REPLAY command only worked
16037
when one of its qualifiers (REPLAY QUIET or REPLAY NONSTOP) was used;
16038
just plain REPLAY didn't work.  The plain REPLAY command now works
16039
correctly.
16040
16041
</div>
16042
16043
<!------------------->
16044
<div class=entry>
16045
16046
The gameinfo.t module has been removed from the base system library.
16047
In its place, the GameID class has been extended to write the GameInfo
16048
data file automatically during pre-initialization.  If the game defines
16049
a GameID object, then the library automatically writes a gameinfo.txt
16050
file, using values from the GameID object.  Refer to the comments
16051
in modid.t for the GameID class.
16052
16053
</div>
16054
16055
<!------------------->
16056
<div class=entry>
16057
16058
Actor.setConvNode() now accepts a string giving the name of a
16059
ConvNode, as an alternative to a reference to a ConvNode object.  In
16060
the past, only the object reference was accepted.  Passing in a
16061
string naming a ConvNode now has the same effect as passing a
16062
reference to the ConvNode itself.
16063
16064
</div>
16065
16066
<!------------------->
16067
<div class=entry>
16068
16069
The new Actor method initiateConversation() makes it easier to code
16070
an NPC initiating a conversation.  This method takes an ActorState
16071
object to use as the NPC's new state, and a ConvNode (which can be
16072
specified by the string name of the ConvNode) to use as the initial
16073
conversation node.
16074
16075
<p>In addition, the new ConvNode method npcGreetingMsg is defined to
16076
display the initial conversational exchange in an NPC-initiated
16077
conversation.  Any ConvNode used in an initiateConversation() call
16078
must either override npcGreetingMsg to define a greeting message, or
16079
define an npcGreetingList property as a TextList containing a list
16080
of greeting messages.
16081
16082
</div>
16083
16084
<!------------------->
16085
<div class=entry>
16086
16087
The new ConvNode method npcContinueMsg is defined to display a
16088
conversational "continuation" message from the actor.  This method
16089
lets the NPC continue a conversation of its own volition if the player
16090
character doesn't do so.  This method is invoked on each turn when the
16091
ConvNode is active, <i>and</i> the player didn't enter a
16092
conversational command on that turn.  The method is invoked during the
16093
actor's takeTurn() daemon processing.  To define a continuation
16094
message, you can either define npcContinueMsg as a double-quoted
16095
string with the message, or you can define npcContinueList to a
16096
TextList subclass containing a list of continuation messages.
16097
16098
<p>If you don't override npcContinueMsg or npcContinueList, there will
16099
be no NPC-initiated continuation message.  If you do provide a
16100
continuation message, then the ConvNode stays active by default.  You
16101
can use the &lt;.convnode&gt; tag within the continuation message's
16102
text to switch to a new ConvNode, just as in a topic response message.
16103
16104
</div>
16105
16106
<!------------------->
16107
<div class=entry>
16108
16109
The commandSequencer now starts in "before-command" mode, rather than
16110
in "no-command" mode.  This allows any introductory text displayed
16111
before the first command to use the normal command sequencing tags.
16112
16113
</div>
16114
16115
<!------------------->
16116
<div class=entry>
16117
16118
The Yes and No topic classes (YesTopic, NoTopic, YesNoTopic) had a
16119
number of bugs that prevented them from working properly.  These
16120
classes should now work correctly.
16121
16122
</div>
16123
16124
<!------------------->
16125
<div class=entry>
16126
16127
A new template for DefaultTopic makes it easier to define these
16128
objects.  The DefaultTopic template accepts simply a response string
16129
(double-quoted), or a list of response strings (single-quoted).
16130
16131
</div>
16132
16133
<!------------------->
16134
<div class=entry>
16135
16136
A bug in the AltTopic mechanism prevented intermediate AltTopics in
16137
nestings more than one level deep from being properly selected.  This
16138
is now fixed.
16139
16140
</div>
16141
16142
<!------------------->
16143
<div class=entry>
16144
16145
In the English-language module, the miscWord production now accepts
16146
'#'-prefaced numbers and quoted strings.  This provides more
16147
flexibility for inputs in things like topic phrases.
16148
16149
</div>
16150
16151
<!------------------->
16152
<div class=entry>
16153
16154
The AccompanyingState class didn't use the correct test for a travel
16155
action in its beforeAction() method, which prevented the class from
16156
carrying out its accompanying travel role at all.  This has been
16157
corrected.
16158
16159
</div>
16160
16161
<!------------------->
16162
<div class=entry>
16163
16164
ActorState.obeyCommand() generated the wrong default message.  This
16165
is now fixed.
16166
16167
</div>
16168
16169
<!------------------->
16170
<div class=entry>
16171
16172
ConvNode had a couple of problems that caused run-time errors or other
16173
strange behavior when activating a ConvNode that had no associated
16174
SpecialTopics.  These have been fixed.
16175
16176
</div>
16177
16178
<!------------------->
16179
<div class=entry>
16180
16181
Fuses and daemons (including real-time events and prompt daemons) now
16182
run automatically in a standard Action environment.  This means that
16183
you can call essentially any library code without having to worry
16184
about whether or not it will need to access gAction or gTranscript.
16185
In the past, fuse and daemon code was called with no Action
16186
environment in effect, which made it necessary to either limit the
16187
library calls made within the fuse or daemon, or to explicitly set up
16188
an action environment (using withActionEnv(), for example) before
16189
invoking library code.  This added a lot of unnecessary complexity
16190
to fuse/daemon code.  Now that these routines are always invoked with
16191
a valid Action environment, these restrictions have been lifted.
16192
16193
</div>
16194
16195
<!------------------->
16196
<div class=entry>
16197
16198
The withActionEnv() method now takes an additional argument, giving the
16199
specific Action class to use for the dummy action object in effect during
16200
the callback.
16201
16202
</div>
16203
16204
<!------------------->
16205
<div class=entry>
16206
16207
The senseContext object's pushSenseContext() and popSenseContext() have
16208
been removed; they've been replaced with a new withSenseContext() method.
16209
16210
<p>In addition, the callWithSenseContext() function has been changed
16211
to eliminate the argument list parameter; instead, callers should use
16212
anonymous functions when the code to be invoked requires arguments.
16213
(This is the way the rest of the library already used the function in
16214
most cases anyway, so this change simply cleans up some old code
16215
that's no longer needed.  Most games won't need to call this function
16216
directly, so this is unlikely to affect any existing game code.)
16217
16218
</div>
16219
16220
<!------------------->
16221
<div class=entry>
16222
16223
The INSTRUCTIONS command now operates either in menu or in-line mode,
16224
not both.  In the past, the menu format supplemented the in-line format,
16225
but this was redundant and complicated the user interface.
16226
16227
</div>
16228
16229
<!------------------------------- 3.0.6h --------------------------------->
16230
<div class="sepbar"><a name='306h'></a>3.0.6h</div>
16231
<p><b><i>Released June 7, 2003</i></b>
16232
<p>
16233
16234
<div class=firstentry>
16235
16236
Several major enhancements to the Actor class have been added.
16237
These changes are described in more detail in the comments in the
16238
library sources files, and in a new series of technical articles on
16239
the <a href='http://www.tads.org'>tads.org</a> web site, <a
16240
href='http://www.tads.org/howto/t3actor.htm'>Creating Dynamic
16241
Characters in TADS 3</a>.  We'll summarize the changes here, but you
16242
should refer to the articles for full details.
16243
16244
<p><b>WARNING!  Due to the extensive scope of these new features,
16245
there's a good chance that they'll undergo some changes as we gain
16246
experience with them.  Be aware that game code that uses these features
16247
might have to be changed to accommodate library changes in future updates.
16248
</b>
16249
16250
<p>A new class, ActorState, makes it easier to create characters that
16251
exhibit multiple behaviors.  The Actor class has been changed to work
16252
with ActorState; most of the methods involved in describing an actor's
16253
physical state and in interacting with an actor are now delegated from
16254
the Actor class to the ActorState object.  The idea is that most of
16255
the parts of an actor that need to vary according to the actor's
16256
behavior have been moved to the new ActorState object; this means that
16257
adding a new behavior to an actor is a matter of defining a new
16258
ActorState object for the actor.
16259
16260
<p>Several subclasses of ActorState have also been created.  These
16261
include ConversationReadyState and InConversationState, which are used
16262
to make an actor explicitly enter, maintain, and exit a conversation;
16263
HermitActorState, for times when an actor is unresponsive; and
16264
AccompanyingState and AccompanyingInTravelState, which allow an NPC to
16265
travel with another character as part of the character's own turns.
16266
16267
<p>A new "topic database" system makes it easier to manage
16268
conversational interactions, by creating individual objects that
16269
represent responses to ASK, TELL, GIVE, SHOW, and other interactions.
16270
The TopicDatabase class is used to store an actor's responses; Actor
16271
and ActorState inherit from TopicDatabase, so you don't normally
16272
create instances of this class directly.  The TopicEntry class
16273
represents a response; several subclasses, including AltTopic,
16274
AskTopic, TellTopic, AskTellTopic, GiveTopic, ShowTopic,
16275
GiveShowTopic, YesTopic, NoTopic, DefaultTopic, and SpecialTopic are
16276
used to create the individual responses.
16277
16278
<p>The conversationManager object and the ConvNode class are used
16279
to manage "threaded" conversations.  A threaded conversation is one
16280
where an actor keeps track of what has been said before, and responds
16281
according to the context of the conversation.
16282
16283
<p>The SuggestedTopic class and its subclasses let you maintain a
16284
"topic inventory," which is a mechanism that automatically suggests
16285
topics to the player.  This is an optional mechanism that you can
16286
use in various ways; you can use it as a sort of hint system, and
16287
you can use it to guide threaded conversations.
16288
16289
</div>
16290
16291
<!------------------->
16292
<div class=entry>
16293
16294
Two library modules have been renamed: 'hints.t' is now 'hintsys.t',
16295
and 'menus.t' is now 'menusys.t'.  Since these modules are included in
16296
most projects using the library file (adv3.tl), this shouldn't require
16297
any changes to any game code or project makefiles.  The new names
16298
better reflect that these modules define the hint and menu systems,
16299
respectively, rather than actual hints or menus.
16300
16301
</div>
16302
16303
<!------------------->
16304
<div class=entry>
16305
16306
A new function, withActionEnv(func), makes it possible for daemon
16307
code to create a simulated Action environment.  Some code relies upon
16308
there being a current Action object and an active command transcript
16309
object; these objects are normally only available while executing a
16310
command, which made it difficult to call code that depends on this
16311
command environment from within a daemon.  This new function makes it
16312
easy to call such code from within daemons and other non-command
16313
contexts.  The function sets up a dummy Action object and a default
16314
command transcript, then invokes the given function; the function can
16315
do anything that can be done during normal Action processing.
16316
16317
</div>
16318
16319
<!------------------->
16320
<div class=entry>
16321
16322
Openable now shows any special descriptions of the contents of an
16323
object that are revealed when the object is opened (via an OPEN
16324
command).
16325
16326
</div>
16327
16328
<!------------------->
16329
<div class=entry>
16330
16331
The English module now includes some needed customizations to the
16332
TopicAction class.  These were missing in the past, which caused
16333
incorrect messages to be generated in some cases involving this
16334
type of action.
16335
16336
</div>
16337
16338
<!------------------->
16339
<div class=entry>
16340
16341
The new class RoomAutoConnector is a subclass of RoomConnector that
16342
can be mixed in to any BasicLocation subclass to make the room usable
16343
directly as a connector to itself.  Room inherits from this class (it
16344
formerly inherited from RoomConnector and overrode part of the
16345
interface; the overrides are no longer necessary because they're
16346
contained in RoomAutoConnector itself now).  In particular,
16347
RoomAutoConnector can be mixed in to any NestedRoom object's
16348
superclasses to make the nested room usable as a connector to itself.
16349
16350
</div>
16351
16352
<!------------------->
16353
<div class=entry>
16354
16355
The new notification methods beforeTravel(traveler, connector) and
16356
afterTravel(traveler, connector) are invoked just before and after a
16357
traveler travels via travelerTravelTo().  These notifications are sent
16358
to each object connected by containment to the traveler;
16359
beforeTravel() is called on each object connected by containment to
16360
the traveler in its old location, and afterTravel() is called on each
16361
object connected by containment in the new location.
16362
16363
<p>These notifications are more precise than using beforeAction() and
16364
afterAction() with the TravelVia pseudo-action, because these actions
16365
are only called when travel is actually occurring.  TravelVia will
16366
fire notifications even when travel isn't actually possible.
16367
16368
<p>A beforeTravel() method can veto the travel action using "exit".
16369
The notification is invoked before the travel is actually performed,
16370
and even before a description of the departure is produced.
16371
16372
</div>
16373
16374
<!------------------->
16375
<div class=entry>
16376
16377
<p>The method Actor.trackFollowInfo() is now invoked from
16378
Actor.beforeTravel() rather than directly from
16379
traveler.travelerTravelTo(), as it was in the past.  This change
16380
makes the follow-tracking a lot less "special," in that it uses the
16381
general before/after travel notification system rather than a
16382
separate, purpose-built notification system.  Note that this change
16383
means that any actor object that overrides beforeTravel() must
16384
inherit the base class implementation if the actor wants to be able
16385
to follow other actors.
16386
16387
</div>
16388
16389
<!------------------->
16390
<div class=entry>
16391
16392
The default travel precondition calculations have been changed
16393
slightly to allow connections between top-level rooms to be placed
16394
inside nested rooms.  This allows, for example, a window that can
16395
only be reached when standing on a desk, or a secret passage from
16396
inside a wardrobe.  The main changes are that TravelVia doesn't
16397
automatically require the traveler to be in the outermost room, but
16398
in the room containing the outbound connector; and travel between
16399
top-level rooms that leaves the traveler inside a nested room (as
16400
would happen when climbing through the window from outside and ending
16401
up on the shelf) now provides a normal arrival message.
16402
16403
<p>First, BasicLocation.roomTravelPreCond() no longer does anything;
16404
the method is still present so that rooms can override it as desired,
16405
but it doesn't do anything by default.  In the past, this method
16406
unconditionally added a precondition requiring that the traveler be
16407
in the outermost room; we don't want to apply that condition, since
16408
the required starting location of the traveler depends on the
16409
outbound connector, not the room.
16410
16411
<p>Second, TravelConnector.connectorTravelPreCond() now adds a
16412
requirement that the traveler be in the connector's location, if the
16413
connector has a location.  This ends up having the same effect as
16414
BasicLocation.roomTravelPreCond() in cases where explicit connectors,
16415
such as doors and passages, are situated in the top-level room.
16416
16417
<p>Third, RoomAutoConnector.connectorTravelPreCond() overrides the
16418
inherited version, and instead requires that the traveler be in the
16419
"appropriate" starting location.  This provides the same effect as
16420
the old BasicLocation.roomTravelPreCond(), but with an enhancement.
16421
The "appropriate" location is defined as the nearest enclosing
16422
location (enclosing the traveler) that has a directional connection
16423
("north = xxx", etc) leading to the room.  In most cases, rooms are
16424
connected directly to one another only at the top level; in such
16425
cases, the directional connection will be found in the traveler's
16426
outermost room, so the effect will be exactly as it was with the old
16427
system.  But here's the enhancement: in cases where the directional
16428
connector is defined leading out of a nested room, this will
16429
correctly find the nested room as the starting location.
16430
16431
<p>Note that NestedRoom objects <b>cannot</b> by default be used as
16432
direct targets of directional connectors, because they're not based
16433
on RoomConnector.  It seems highly unlikely that it would ever be
16434
useful to connect a nested room directly to a directional connector
16435
(i.e., "east = wardrobe") - some kind of explicit connector (a door,
16436
or a passage, or something) seems desirable in almost every case,
16437
just from the perspective of game geography.  In the event that a
16438
direct directional connector is required, though, simply include
16439
RoomAutoConnector in the superclass list for your specific nested
16440
room.
16441
16442
<p>Fourth, the methods travelerArriving() and travelerLeaving() have
16443
been moved from Room to BasicLocation.  This produces the proper
16444
travel messages for any travel between top-level locations, even when
16445
the travel starts or ends in a nested location.
16446
16447
</div>
16448
16449
<!------------------->
16450
<div class=entry>
16451
16452
BasicLocation.travelerArriving() now enforces the defaultPosture
16453
setting for the location.  The default posture is enforced via a
16454
nested command before the arrival message is displayed.  This makes
16455
it easier to create locations with restrictions on posture, such as a
16456
low crawl where you can only sit or lie down.
16457
16458
<p>Note that if all goes well, there won't be any mention of the
16459
action for the player character (because the successful nested action
16460
will result in a default report, which will be suppressed due to the
16461
non-default message for the room description); so the new posture
16462
will simply be reflected in the description of the new location.
16463
Generally, all should always go well in these cases, since the actor
16464
will already be located within the location and merely has to change
16465
posture.  If you want to explain why the posture change is necessary,
16466
you can override travelerArriving() for the location, display an
16467
explanation, then inherit the default.  An appropriate message would
16468
be something like "The ceiling is so low you have to lie down." 
16469
16470
</div>
16471
16472
<!------------------->
16473
<div class=entry>
16474
16475
The semantics of TravelConnector.getDestination() have been changed
16476
slightly.  First, the method now takes a traveler rather than an
16477
actor, since connectors are always traversed by travelers.  (A
16478
traveler might in fact turn out to be an actor, of course, but it
16479
could also be something else, such as a vehicle.)  Second, the method
16480
is now required to return the destination, and the destination must be
16481
stable for the duration of the turn up to the point where the travel
16482
actually occurs.
16483
16484
<p>To allow for connectors that are affected by traversal (for
16485
example, a connector that randomizes its destination each time it's
16486
used), the new method noteTraversal() must be called whenever the
16487
connector is actually traversed.  This method can change the connector
16488
state as needed for the traversal.  Note that game code should
16489
generally never need to call noteTraversal(), as the library
16490
dobjFor(TravelVia) action implementations do this automatically as
16491
needed.  This method is provided for games to override as needed.
16492
16493
</div>
16494
16495
<!------------------->
16496
<div class=entry>
16497
16498
The base TAction and TIAction classes no longer require that any of
16499
the target objects of the command define an action() method for the
16500
verb.  Instead, the classes now merely require that at least one of
16501
the target objects defines any of action(), check(), or verify().  If
16502
none of the target objects defines any of these methods for the verb,
16503
then the verb will automatically add an "illogical" status during the
16504
verify phase.
16505
16506
<p>The purpose of this check is to ensure that the command has
16507
<i>some</i> sort of handling.  If the game adds a new verb, but never
16508
defines any handling at all for the new verb for some object, then
16509
without this check, there would be no handling at all if the player
16510
attempted to apply the verb to that object.  The old check tested for
16511
the existence of an action() handler, but this was overly
16512
conservative, since an object could have fully handled the verb in its
16513
verify() or check() handler.  The new test allows for this by allowing
16514
the action to proceed if any sort of handler (check, verify, or
16515
action) is defined for an object involved in the command.
16516
16517
</div>
16518
16519
<!------------------->
16520
<div class=entry>
16521
16522
A new property, globalParamName, has been added to Thing.  This lets
16523
you define a substitution parameter string (for "{xxx}" sequences)
16524
that can be used at any time to refer to the object in message text.
16525
Once you define an object as having a global parameter name, you can
16526
use that name to refer to the object in {xxx} sequences, even when no
16527
command is active, and even when the object isn't involved in any
16528
command.  This can be especially useful for writing messages that
16529
refer to objects whose names change in the course of the game, such as
16530
actors who are known by one name until introduced, then are known by
16531
another name ("the white-haired man" might become "Bob" after he tells
16532
us his name, for example).
16533
16534
</div>
16535
16536
<!------------------->
16537
<div class=entry>
16538
16539
A new Script subclass, EventList, provides a convenient way of
16540
defining scripts using procedural code in steps without writing a big
16541
'switch' statement in the doScript() method.  The eventList property
16542
contains a list of script step elements.  Each element gives one step
16543
of the script.  An element can be a single-quoted string, in which
16544
case the string is simply displayed; a function pointer, in which case
16545
the function is invoked with no arguments; a ScriptEvent object, in
16546
which case the object's doEvent() method is invoked; or nil, in which
16547
case nothing happens on the step.
16548
16549
</div>
16550
16551
<!------------------->
16552
<div class=entry>
16553
16554
The Actor method getDefaultInterlocutor() has been renamed to
16555
getCurrentInterlocutor(), to better reflect its purpose.  The
16556
conversation model keeps track of the actor we're currently talking
16557
to; conversational commands that aren't directed to a specific actor
16558
(such as ASK ABOUT BOOK) are assumed to be directed to the current
16559
conversational partner.
16560
16561
</div>
16562
16563
<!------------------->
16564
<div class=entry>
16565
16566
A couple of the abstract base classes in the area of Container have
16567
been renamed to better reflect their purposes.  The class formerly
16568
known as BasicContainer is now called BulkLimiter, and the class
16569
formerly known as Encloser is now called BasicContainer.  So, Container
16570
is a BasicContainer, which is a BulkLimiter; Surface is also a
16571
BulkLimiter.  The new name BulkLimiter is more consistent with its
16572
main purpose, which is to constrain the aggregate bulk of its
16573
contents.  The old name "Encloser" was confusingly similar to the
16574
real word "Enclosure," and was vague in conveying how the class
16575
differs from Container; the new name BasicContainer makes it clearer
16576
that this class contains some of the basic abstract functionality
16577
of Container but 
16578
16579
</div>
16580
16581
<!------------------->
16582
<div class=entry>
16583
16584
The actor inventory listing mechanism has been reworked to make it a
16585
smarter about the listing format.  When the inventory list is short,
16586
the listing will appear in a single sentence showing both the items
16587
being carried and the items being worn.  When the listing is long,
16588
it's broken up into two sentences, as in the past.  The threshhold for
16589
"long" is set with a property of the new DividedInventoryLister class,
16590
singleSentenceMaxNouns; the default is 7, which means that the listing
16591
will be shown in one sentence if it involves seven items of fewer, two
16592
sentences otherwise.  For example:
16593
16594
<p>
16595
<pre>
16596
  &gt;inventory
16597
  You are carrying a music box, a gold coin, and thirty silver coins,
16598
  and you're wearing a watch and a helmet.
16599
16600
  &gt;inventory
16601
  You are carrying a cardboard box (which contains several LP's, a
16602
  bunch of photographs, and some letters), a rubber chicken, two
16603
  pieces of the Magic Goblet of Forblotsk, and a bowl of chowder.
16604
  You're wearing a pair of flippers, a wool jacket, and a red wig.
16605
</pre>
16606
16607
<p>The list length is determined by capturing the output and counting
16608
the phrase separators.  The English library counts commas, semicolons,
16609
the word "and", and right parentheses to determine the phrase count.
16610
16611
<p>This change slightly affects the Actor class (showInventoryWith now
16612
takes only one lister object), and extensively affects the
16613
InventoryLister class and the WearingLister class and their subclasses
16614
(the English-specific implementations in msg_neu.t).  Games shouldn't
16615
be affected unless they modified these classes.
16616
16617
<p>If you want the old behavior, where the items being worn and the
16618
items being carried were always shown as separate sentences, simply
16619
set DividedInventoryLister.singleSentenceMaxNouns to zero.  If you
16620
want to always use a single sentence no matter what, set the property
16621
to some absurdly high number - 30000, say.
16622
16623
<p>If you'd prefer the more traditional behavior that shows the items
16624
being worn marked "(being worn)" and mixed in with the rest of the
16625
inventory in a single listing, simply change Actor.inventoryLister
16626
to refer to actorSingleInventoryLister.
16627
16628
</div>
16629
16630
<!------------------->
16631
<div class=entry>
16632
16633
The match list for an ALL phrase in player input is now filtered
16634
through the filterResolveList() method of each object in the list,
16635
just as ambiguous noun phrases are.  This allows objects that
16636
substitute for others in resolution lists (such as Collective and
16637
CollectiveGroup objects) to perform the same substitutions in ALL
16638
lists that they would in normal matches.
16639
16640
</div>
16641
16642
<!------------------->
16643
<div class=entry>
16644
16645
The miscWord grammar rules are now defined in en_us.t, rather than
16646
in the language-independent parser.t as they were previously.  This
16647
change is necessary because different languages might have different
16648
token types that are valid in miscellaneous word lists.  (In point of
16649
fact, the English parser defines a special language-specific token,
16650
tokApostropheS, that is now allowed in miscellaenous word lists.)
16651
16652
</div>
16653
16654
<!------------------->
16655
<div class=entry>
16656
16657
The menu system now uses the regular game color scheme as the
16658
defaults; the top "instructions" bar is shown using the status line
16659
color scheme, and the main menu area uses the normal game window color
16660
scheme.  This scheme is the safest default, since it uses only colors
16661
the user has selected (on interpreters that allow the user to select
16662
the color scheme); this ensures in particular that things like
16663
hyperlink colors work well with the menu colors, since presumably the
16664
user will have chosen settings that work well together.  (If not, at
16665
least it's not the game's fault.)  This change means that menus won't
16666
stand out as well from the main game window, since they use the same
16667
color scheme, so the default mode for menus has been changed to the
16668
"full screen" mode.  This new default appearance - full screen, using
16669
normal game and status-line colors - makes menus very unobtrusive,
16670
since they just look like an ordinary game screen.
16671
16672
</div>
16673
16674
<!------------------->
16675
<div class=entry>
16676
16677
The menu system takes advantage of the new MORE-mode banner style
16678
option, by using a separate banner to show "long topic" items.  Since
16679
long text can now safely be displayed in a banner, with the interpreter
16680
providing pagination via MORE prompts as needed, long topics can avoid
16681
taking over the main game window.  This is nice because it leaves the
16682
original game window intact (without any need to clear the screen) after
16683
the user exits from the menu system.
16684
16685
</div>
16686
16687
<!------------------->
16688
<div class=entry>
16689
16690
The MenuItem class has a new property, heading, that specifies the
16691
text to display as the heading of the menu while the menu is active.
16692
By default, the heading is the same as the title, which is the string
16693
displayed in the parent menu's list of items.  The separate property
16694
allows the caption shown while the menu is active to differ from its
16695
title, if this is desired.
16696
16697
</div>
16698
16699
<!------------------->
16700
<div class=entry>
16701
16702
A couple of the English messages for the npcMessagesDirect group have
16703
been recast as quoted statements from the NPC, for consistency with
16704
other messages in the group.  The affected messages are
16705
noMatchDisambig and disambigOrdinalOutOfRange.  In addition,
16706
askDisambig (in the same group) has been tweaked slightly to
16707
accommodate this change.
16708
16709
</div>
16710
16711
<!------------------->
16712
<div class=entry>
16713
16714
The CollectiveGroup class has been split into two classes.  The full
16715
behavior of the old class is now contained in the class
16716
ItemizingCollectiveGroup, which is a subclass of CollectiveGroup.  On
16717
Examine, the CollectiveGroup class no longer shows the itemized list
16718
of collected items, but instead simply shows its own description using
16719
the normal Examine handling.  The itemizing behavior is desirable in
16720
some cases of collective groups, but certainly not all; this change
16721
makes it easy for the game to select whether or not the itemizing
16722
behavior is used.
16723
16724
</div>
16725
16726
<!------------------->
16727
<div class=entry>
16728
16729
If a check() routine (in a dobjFor() or iobjFor() group) terminates
16730
the command with 'exit', the parser now automatically marks the action
16731
in the transcript as having failed.  This is the same thing that the
16732
reportFailure() macro does, so this means that it's never necessary
16733
to use reportFailure() from within a check() handler.  Since the purpose
16734
of check() is to enforce conditions on the action, exiting from the
16735
check() routine necessarily means that the command has failed; this
16736
change takes advantage of that to save games a bit of work.
16737
16738
</div>
16739
16740
<!------------------->
16741
<div class=entry>
16742
16743
A new set of grammar productions provide for third-person reflexive
16744
pronouns in verbs with two noun-phrase slots: "put klein bottle in
16745
itself," for example.  These are mostly intended for conversation,
16746
specifically things like "ask bob about himself," but will work in
16747
general for the rare cases where they might be useful.
16748
16749
<p>The parser resolves a third-person reflexive pronoun by referring
16750
back to the resolved object list for the other noun phrase in the
16751
action.  Verbs taking only one noun phrase don't accept these, as they
16752
make no sense: "open itself" isn't meaningful.  In the basic TIAction,
16753
the order of noun phrase resolution can vary by verb, and the order
16754
of resolution isn't required to match the order of the nouns in the
16755
phrase; in English, at least, a reflexive pronoun in this type of
16756
construction is always anaphoric (i.e., it always refers to a phrase
16757
earlier in the sentence).  This means that the TIAction resolver could
16758
find itself trying to resolve the reflexive phrase first, before it
16759
knows the resolution of the phrase to which the reflexive refers.
16760
To cope with this situation, the resolver notes when this occurs,
16761
provides an empty list for the initial resolution of the reflexive,
16762
and then goes back and re-resolves the reflexive after resolving
16763
the other noun phrase.
16764
16765
</div>
16766
16767
<!------------------->
16768
<div class=entry>
16769
16770
The new Thing property isKnown lets you specify that an object is
16771
known in advance to the actors in the game.  The method isKnownBy(actor)
16772
can be used to test actor knowledge of a Thing: isKnownBy(actor) returns
16773
true if seenBy(actor) returns true, or the isKnown property is set to
16774
true for the object.  The Actor methods knowsTopic() and isLikelyTopic()
16775
now use isKnownBy() rather than seenBy() to determine actor knowledge.
16776
16777
</div>
16778
16779
<!------------------->
16780
<div class=entry>
16781
16782
A few new conversation-related verbs have been added: Goodbye,
16783
Yes, and No.  These are handled similarly to Hello.
16784
16785
</div>
16786
16787
<!------------------->
16788
<div class=entry>
16789
16790
A new Action method, isConversational(issuingActor), determines if an
16791
action is "conversational."  A conversational action is one that
16792
involves the issuing actor saying something, within the game context,
16793
to the target actor, as opposed to an order to the target actor to do
16794
something.  Of the system-defined verbs, Hello, Goodbye, Yes, No, and
16795
TellAbout (with the issuing actor as the direct object) are defined
16796
as conversational.
16797
16798
</div>
16799
16800
<!------------------->
16801
<div class=entry>
16802
16803
The interface of the Actor.obeyCommand() has changed, as has its meaning.
16804
The method now takes two parameters: the actor who issued the command, and
16805
the Action object.  In the past, this method was called with only the
16806
issuing actor as a parameter, because the action was unresolved when the
16807
method was called.  Now, the parser calls this method <i>after</i>
16808
resolving the action and its objects.  This change gives the method
16809
full access to the details of the action, so it can decide to accept
16810
or reject commands based on the actual action being performed.
16811
16812
<p>The parser <i>does not</i> call this method when the action is
16813
"conversational," as indicated by the isConversational() method no the
16814
action.  Conversational methods are not considered to involve an order
16815
to the target actor.  The actual physical action of a conversational
16816
action simply consists of the issuing actor saying something to the
16817
target actor, so even though these actions are phrased as though
16818
they're orders to the target actor, they're really carried out by the
16819
issuing actor, and thus don't require acceptance by the target actor.
16820
16821
<p>The default implementation of this method on Actor calls the
16822
corresponding method on the atcor's current state object.  The
16823
basic state object implementation simply refuses the command, so the
16824
default behavior is the same as it was in the past.
16825
16826
</div>
16827
16828
<!------------------->
16829
<div class=entry>
16830
16831
The TextList subclass formerly known as SlaveTextList has been
16832
renamed to SyncTextList, to better reflect that this list is always
16833
kept synchronized with its associated master list.  The old name
16834
suggested that the connection was one-way, that state changes flowed
16835
only from the master to the slave, when in fact the master and slave
16836
are fully synchronized.  The new name is more suggestive of this
16837
two-way connection.
16838
16839
</div>
16840
16841
<!------------------->
16842
<div class=entry>
16843
16844
A new TextList subclass, StopTextList, provides a minor variation on
16845
the standard text list script.  Once StopTextList reaches its last
16846
message, it will simply stay at the last message forever, repeating
16847
the last message each time the script is invoked.  This is useful for
16848
cases such as a conversation topic where an actor has several things
16849
to say, but once the actor has said each bit, the actor will from
16850
that point on just repeat the last message; the last message would
16851
usually be something like "I've already told you all I know about
16852
it," or could be a summary of what the actor revealed.
16853
16854
</div>
16855
16856
<!------------------->
16857
<div class=entry>
16858
16859
ShuffledTextList features a few enhancements. 
16860
16861
<p>First, a new property, firstStrings, can be set to a list of
16862
strings to show sequentially before starting the shuffled strings.
16863
This can be useful in cases where you have some meaningful
16864
information to convey initially, but once those messages have been
16865
displayed, you want to fall back on randomized messages for
16866
atmosphere and variety.  The firstStrings list is shown only once, in
16867
sequential order.  Once the firstStrings list is exhausted, these
16868
strings are never shown again.
16869
16870
<p>Second, the main shuffled list in textStrings can now be shown
16871
sequentially the first time through, if desired.  Set the property
16872
shuffleFirst to nil (it's true by default) if you don't want the list
16873
shuffled the first time through.  Since the strings in the textStrings
16874
list are intended to be shown in random order, in most cases it won't
16875
matter to the author what order is used, and in this sense the order
16876
in which the strings are actually defined is as random as any other
16877
order.  In some cases, it might actually be desirable to have the
16878
strings come out in a certain order the first time through; this lets
16879
you refer back to an earlier message in a later message, for example,
16880
with assurance that the player will have always seen the earlier
16881
message first.  After the first time through the list, the list is
16882
always shuffled and shown again in random order.
16883
16884
<p>Third, the class now takes care to ensure that a message is never
16885
repeated consecutively.  Repeats are normally avoided naturally by
16886
the shuffling: every item is shown once before anything is repeated.
16887
But a consecutive repeat was still possible in one special case,
16888
which is immediately after a shuffle.  Because the order of one
16889
shuffle is independent of the order of the next shuffle, it was
16890
possible for the last element of the previous shuffle to be the same
16891
as the first element of the next shuffle.  The class now suppresses
16892
this case by checking each new shuffle to make sure its first element
16893
doesn't match the last element of the previous shuffle, and choosing
16894
again when necessary.  This change is intended to increase the
16895
apparent randomness by ensuring that the same string is never shown
16896
twice in a row.
16897
16898
</div>
16899
16900
<!------------------->
16901
<div class=entry>
16902
16903
The special description list order has been modified slightly.  If two
16904
objects have the same specialDescOrder value, but one of the two
16905
objects is inside the other, we'll list the outer object first.  So,
16906
specialDescOrder still dominates, but when there's no specialDescOrder
16907
preference, we'll list containers before their children.  In almost
16908
all cases, this produces a more pleasing list order; objects within
16909
other objects will frequently mention their placement in their special
16910
description text, so it's usually better to have seen the containing
16911
item's own special description before we see the containing item
16912
mentioned in a child item's special description.
16913
16914
</div>
16915
16916
<!------------------->
16917
<div class=entry>
16918
16919
A set of new commands makes it easier to record and play back command
16920
scripts, which can be especially useful while writing and testing a
16921
game.  The command RECORD (RecordAction) starts recording a command
16922
script, which saves command input text to a file.  RECORD OFF
16923
(RecordOffAction) turns off the recording starting with RECORD (it has
16924
no effect if no recording is in progress).  REPLAY (ReplayAction)
16925
plays back a command script previously recorded.  RECORD and REPLAY
16926
both accept a filename in quotes on the command line, but this is
16927
optional; if you just type RECORD or REPLAY, the commands will ask you
16928
to select a file using a standard file dialog.
16929
16930
<p>REPLAY has two mutually exclusive options.  REPLAY QUIET plays
16931
back the script without showing any output while the script is running.
16932
REPLAY NONSTOP plays back the script without pausing for MORE prompts.
16933
16934
<p>Because REPLAY is fully redundant with the old "@" syntax, but much
16935
friendlier, the "@" syntax has been removed.
16936
16937
</div>
16938
16939
<!------------------->
16940
<div class=entry>
16941
16942
The new class LocateInParent makes it easy to define a nested object
16943
that's to be located within the enclosing object.  This is a mix-in
16944
superclass, so simply add it to the object's superclass list;
16945
LocateInParent should go ahead of Thing or any Thing subclass in the
16946
superclass list.
16947
16948
</div>
16949
16950
<!------------------------------- 3.0.6g --------------------------------->
16951
<div class="sepbar"><a name='306g'></a>3.0.6g</div>
16952
<p><b><i>Released April 12, 2003</i></b>
16953
<p>
16954
16955
<div class=firstentry>
16956
16957
The default object picker has been improved to better handle cases
16958
where commands are remapped.  Remapping from one object to another is
16959
often used as a convenience to the player, so that the same command
16960
can be applied to any of several related objects with the same
16961
effect.  For example, you might want to set up a jar with a lid so
16962
that OPEN JAR and OPEN LID have the same effect; this could be done
16963
by remapping OPEN LID to OPEN JAR.  Similarly, a house with a door
16964
might remap ENTER HOUSE so that it's handled as ENTER DOOR.  In the
16965
past, cases like these prevented the parser from choosing a default
16966
object, because the parser can only apply a default when there's only a
16967
single object that could make sense - the remappings made several
16968
different objects look equally good superficially, even though the
16969
apparent different possibilities were all going to turn into the same
16970
thing in the end thanks to the remapping.
16971
16972
<p>The parser now keeps track, during the verification process, of
16973
any remapped objects.  The default picker looks at this remapping
16974
information before deciding on a default.  If there are any objects
16975
among the possible defaults that are to be remapped, the default
16976
picker will discard any that are redundant due to the remappings.
16977
For the OPEN JAR/OPEN LID example, the parser would see that OPEN LID
16978
turns into OPEN JAR, and it would thus discard the lid from the list
16979
of possible defaults, since the jar is already in the list.  This
16980
would leave us with just one possibility, so the parser would be able
16981
to apply use it as the default.
16982
16983
<p>The parser will only eliminate a remapped object as redundant
16984
when the remapping matches the object, action, and role of another
16985
object in the list of possible defaults.  If a remapping changes the
16986
verb, the remapped object will only match another object if it's also
16987
remapped to that same new verb.  The verb has to match because the
16988
command could otherwise have a different effect, and thus the two
16989
actions on the same object wouldn't be redundant with one another.
16990
16991
</div>
16992
<!------------------->
16993
<div class=entry>
16994
16995
The asExit() macro has been changed slightly.  You should no longer
16996
uses the ":" syntax to define the direction; instead, simply put
16997
the asExit macro directly after the direction name:
16998
16999
<p><pre>  north asExit(down)
17000
</pre>
17001
17002
<p>This change is intended to make asExit more consistent with
17003
the similarly-named asDobjFor() and related macros.
17004
17005
</div>
17006
17007
<!------------------->
17008
<div class=entry>
17009
17010
The menu system has a few minor changes to make the user interface
17011
more easily customizable.
17012
17013
<ul>
17014
  <li>In HTML interpreters, the top title/instructions bar now shows
17015
   a hyperlink that returns to the parent menu.  The text in this
17016
   hyperlink is controlled by the 'prevMenuLink' property, which
17017
   by default uses the text 'Previous'.
17018
17019
  <li>In HTML interpreters, a hyperlink is shown in topic lists to
17020
   advance to the next topic item.  The text of the hyperlink is given
17021
   by the 'nextMenuTopicLink' property.
17022
17023
  <li>The 'fgcolor' and 'bgcolor' properties now look to the parent
17024
   menu, if there is a parent menu, for their default values.  For
17025
   the top-level menu, the defaults are still the status line colors.
17026
   In most cases, you'll want all of the menus in an entire menu tree
17027
   to have the same appearance, and this change makes it easy to
17028
   accomplish this: simply specify the appearance in the top-level
17029
   menu, and all of the child menus will use the parent menu settings.
17030
   Of course, individual menus can sever this parental dependence simply
17031
   by overriding these properties.
17032
17033
  <li>Two new properties, 'topbarfg' and 'topbarbg', allow each menu to
17034
   specify the foreground (text) and background colors of the top
17035
   title and instructions bar.  By default, these look to the parent
17036
   menu, if there is one; the top-level menu defaults to using the
17037
   inverse of the color scheme of the menu itself.
17038
17039
  <li>The 'indent' property uses the parent's value by default.
17040
17041
  <li>A new property, 'fullScreenMode', lets you indicate that you want
17042
   the menu to take over the entire interpreter window.  By default,
17043
   menus are given just enough space at the top of the interpreter
17044
   window to display their contents.  If 'fullScreenMode' is true,
17045
   though, menus will cover the entire interpreter window.  Full-screen
17046
   mode has the advantage that it's less jumpy than the default
17047
   partial-screen mode, since the partial mode resizes the menu windows
17048
   on each navigation operation to accommodate the new contents.
17049
</ul>
17050
17051
</div>
17052
17053
<!------------------->
17054
<div class=entry>
17055
17056
A new hint menu type has been added: HintLongTopicItem.  This is
17057
simply a MenuLongTopicItem subclass designed for use in hint menus.
17058
(Regular HintLongTopicItem objects don't have the necessary logic for
17059
calculating visibility in a hint menu, so the specialized subclass
17060
should be used for long-topic menus within hint menu trees rather
17061
than the base MenuLongTopicItem type.)
17062
17063
</div>
17064
17065
<!------------------->
17066
<div class=entry>
17067
17068
The library's turn-counter incorrectly counted a command as two turns
17069
if the command's action() handler invoked a nested action which was
17070
then remapped (via remapTo).  Nested actions aren't supposed to count
17071
as separate turns; it was erroneous for the remapping to affect this
17072
one way or the other.  This has been corrected.
17073
17074
</div>
17075
17076
<!------------------->
17077
<div class=entry>
17078
17079
moveInto(nil) now works properly for a MultiLoc object.  (In the past,
17080
this incorrectly caused a run-time error.)
17081
17082
</div>
17083
17084
<!------------------->
17085
<div class=entry>
17086
17087
SensoryEmanation has a new property, isAmbient.  This is nil by default;
17088
if set to true, it indicates that the noise/odor/etc is purely in
17089
the background, so it's not especially noticeable.  Ambient emanations
17090
won't be mentioned when they first become sensed; normally, an emanation
17091
is automatically mentioned whenever conditions change so that it was
17092
not sensed previously but is now.  Ambient emanations will still be
17093
mentioned in explicit intransitive LISTEN/SMELL commands; they simply
17094
won't be mentioned on their own.
17095
17096
</div>
17097
<!------------------->
17098
<div class=entry>
17099
17100
Part of the Container class has been separated into a new lower-level
17101
base class, Encloser.  An Encloser is an object that can enclose its
17102
contents, so that all senses must pass through the encloser's
17103
material when passing in and out of the object.  Encloser has all
17104
of the basic handling for enclosing contents, but not the action
17105
handling.  Encloser is meant for cases where the object's contents
17106
are not to be directly manipulable by the player, via "put in"
17107
commands and the like.  Container is now a subclass of Encloser;
17108
Container defines the suitable action handlers to allow a player
17109
to manipulate the container's contents.
17110
17111
</div>
17112
<!------------------->
17113
<div class=entry>
17114
17115
<p>
17116
A new mechanism in the Actor class makes it relatively easy to set it
17117
up so one or more non-player characters accompany the player character
17118
on travel.  This kind of group travel is especially good for things
17119
like a sidekick character who goes everywhere the player does, and for
17120
tour guides or other escorts who are showing the player character
17121
where to go.
17122
17123
<p>This mechanism is similar to the "follow" mechanism, which makes
17124
one actor attempt to follow another on each turn, but it improves
17125
considerably on regular following by customizing the messages.  Normal
17126
following is a little awkward for explicit group travel of the sort
17127
that one wants with sidekicks and escorts, because the messages are so
17128
generic; the NPC almost seems to be wandering around on its own and
17129
just coincidentally showing up where the PC is.  This new
17130
"accompanying" mechanism accomplishes much the same thing, but smooths
17131
out the messages a bit.  First, rather than having the NPC trailing
17132
along after the fact, the new system sends accompanying NPC's on
17133
ahead; this means that the NPC's don't just wander in later as they do
17134
with normal following.  Second, the message for the NPC's
17135
pre-departure is customized to make it clear that the NPC isn't
17136
departing, but is coming along with you.  Third, on arriving in the
17137
new location, there's a customization hook for describing the NPC's
17138
presence in the new location specially for the group travel; this is
17139
important because it gives us a place to mention that the actor starts
17140
doing whatever it is the actor normally does in the new location.  The
17141
overall effect is that each group travel action is made to look like a
17142
single, integrated action, rather than two generic and unrelated actor
17143
travel actions.
17144
17145
<p>NPC's can also be set to accompany NPC's with the same mechanism,
17146
but it's much less interesting for that, since the main value of the
17147
new mechanism is that it improves the messages for PC-plus-NPC group
17148
travel.  For NPC-plus-NPC group travel, this new mechanism has no
17149
particular advantage over the the simpler "follow" mechanism.
17150
17151
<p>Setting up accompanying travel is relatively straightforward.
17152
You have to specify the conditions under which the group travel occurs,
17153
and you should customize two messages related to the travel.  You
17154
set this all up by overriding methods on the NPC who's going to follow
17155
the lead actor (usually the PC).  The methods to override are as
17156
follows.
17157
17158
<p>First, override the accompanyTravel() method so that it returns
17159
true under the conditions where you want the accompanying travel to
17160
occur.  This method is called each time your NPC is present and sees
17161
another actor attempt a travel action (it's called during your NPC's
17162
beforeAction when the action is a TravelVia).  If you want your actor
17163
to accompany the PC everywhere, simply return true when the action
17164
actor is the PC.  The method also has access to the TravelConnector
17165
involved in the travel, so you selectively accompany an actor for
17166
some destinations but not others, if you wish.
17167
17168
<blockquote>
17169
<b>Warning: the next two parts are likely to be modified soon.</b>
17170
I'd recommend against writing any code that makes customizations using
17171
these features right now.
17172
</blockquote>
17173
17174
<p>Second, define an accompanyDesc method for your actor.  This method
17175
is used instead of the usual actorHereDesc method to describe your
17176
actor in the new location immediately after the group travel is
17177
finished.  It's usually desirable to use a special message to describe
17178
the actor right after the accompanying travel, because you usually
17179
want to convey that the actor is just arriving - not that the actor is
17180
walking in separately from the lead actor, but that the actor is
17181
arriving at the same time as the lead actor.  If you do override
17182
accompanyingDesc, you should override accompanyingListWith to return
17183
an empty list ([]).
17184
17185
<p>Third, you can optionally provide a special TravelMessageHandler
17186
for your actor by overriding getAccompanyingTravelMessageHandler.  By
17187
default, this routine provides a message handler that uses messages
17188
like "Bob goes with you" instead of the usual "Bob leaves to the east"
17189
to describe the departure of your actor.  The normal departure message
17190
isn't appropriate, because the actor isn't just leaving, it's leaving
17191
*with* the lead actor.  The default "Bob goes with you" is better, but
17192
you might still want to override this handler to provide even more
17193
customized messages: "Bob escorts you to the east," or "You drag Bob
17194
with you," or whatever makes sense for the specific situation.
17195
17196
<p>Finally, note that you can use accompanying travel and the regular
17197
following mechanism together.  Regular following can be a useful
17198
fallback for cases you don't want to customize.  Regular following
17199
occurs after the fact, because it occurs on an NPC's turn when the
17200
NPC sees that the actor it's tasked to follow is no longer present.
17201
Accompanying travel, in contrast, happens on the same turn as the
17202
lead actor's travel.  This means that regular following is essentially
17203
overridden by accompanying travel, since it happens first.  
17204
17205
</div>
17206
17207
<!------------------->
17208
<div class=entry>
17209
17210
The English parser now accepts quoted strings as adjectives.  Quoted
17211
strings can be used as adjectives in exactly the same way that numbers
17212
can be used, so phrases such as "QU" TILE and BUTTON "G" are accepted.
17213
17214
<p>For the purposes of matching vocabulary in the dictionary, quoted
17215
adjectives are simply treated as though the quotes weren't present.
17216
So, "QU" TILE is treated exactly the same as QU TILE.  This means you
17217
don't have to worry about the quotes when defining your vocabulary
17218
words.
17219
17220
<p>There is an additional bit of special treatment for quoted strings.
17221
The special vocabulary word '"*"' (that is, an asterisk within
17222
double-quote characters) serves as a wildcard for any quoted string.
17223
If an object defines this special wildcard as an adjective among its
17224
vocabulary words, then that object will match <i>any</i> quoted string
17225
as an adjective.  This is the equivalent of the '#' wildcard string
17226
for numeric adjectives.
17227
17228
<p>String-as-adjective phrasing is implemented using the new
17229
production literalAdjPhrase.  This new production is now used
17230
wherever numberPhrase was formerly used in the role of an adjective
17231
in noun phrase rules.  literalAdjPhrase matches numbers, '#' number
17232
phrases, and quoted strings.
17233
17234
</div>
17235
17236
<!------------------->
17237
<div class=entry>
17238
17239
In travel.t, there were formerly a couple of TravelConnector
17240
subclasses that handled action synonyms for TravelVia using
17241
asDobjFor(TravelVia).  These have been changed to use
17242
remapTo(TravelVia) instead.
17243
17244
<p>The asDobjFor() approach had the drawback that the action
17245
synonyms didn't ever generate TravelVia actions proper, but
17246
simply called the TravelVia handlers internally; so, for example,
17247
beforeAction() routines wouldn't ever see a TravelVia action
17248
being performed.  The new remapping approach is better because
17249
it means that every possible action on these objects that
17250
involves travel will go through an actual TravelVia action.
17251
This allows beforeAction() and similar routines to be assured
17252
that they can catch all travel actions by looking for TravelVia
17253
alone, eliminating the need to worry about synonym actions that
17254
could cause travel.
17255
17256
</div>
17257
17258
<!------------------->
17259
<div class=entry>
17260
17261
A couple of new classes simplify a few tasks involving entry
17262
and exit portals.  Exitable is a new class that's similar to
17263
Enterable, but provides Exit instead of Enter as its main
17264
action.  EntryPortal and ExitPortal are just like Enterable and
17265
Exitable, respectively, but add support for GoThrough actions.
17266
17267
</div>
17268
17269
<!------------------->
17270
<div class=entry>
17271
17272
Added finishOptionFullScore, to make it easy for the game to
17273
offer the player the option of seeing the full score at completion.
17274
17275
</div>
17276
17277
<!------------------------------- 3.0.6f --------------------------------->
17278
<div class="sepbar"><a name='306f'></a>3.0.6f</div>
17279
<p><b><i>Released March 23, 2003</i></b>
17280
<p>
17281
17282
<div class=firstentry>
17283
17284
It's now less dire for gPlayer.location to be set to nil.  In the
17285
past, setting gPlayer.location to nil caused an infinite error loop,
17286
because the status line code dereferenced gPlayer.location without
17287
checking for nil, which caused an error, which aborted the current
17288
turn, which started a new turn, which tried to update the status
17289
line, and around we went.  It's still not completely valid for
17290
gPlayer.location to be nil; this change just removes the infinite
17291
error loop, which makes it a little easier to deal with this problem
17292
arising during programming and testing.
17293
17294
</div>
17295
17296
<!------------------->
17297
<div class=entry>
17298
17299
Changed Thing.dobjFor(Remove) to remap to RemoveFrom (asking for an
17300
iobj).  Wearable now overrides Remove to map it to Doff.  It makes
17301
more sense in general for "remove foo" to mean "remove foo (from
17302
something)" rather than "doff foo"; only when "foo" is an article of
17303
clothing does the "doff" interpretation usually apply.
17304
17305
</div>
17306
17307
<!------------------->
17308
<div class=entry>
17309
17310
Added the new TravelConnector property isConnectorListed.  If this
17311
property is nil, the connector is suppressed from generated exit
17312
lists (such as the status line exit list, and "you can't go that way"
17313
messages).
17314
17315
</div>
17316
17317
<!------------------->
17318
<div class=entry>
17319
17320
Added a new class, UnlistedProxyConnector, that acts as a proxy for
17321
an underlying connector, but is unlisted.  The idea is to make it
17322
easy to add an exit that acts exactly like another connector, but is
17323
suppressed from exit lists.
17324
17325
</div>
17326
17327
<!------------------->
17328
<div class=entry>
17329
17330
Added a macro, asExit(), that can be used to define an
17331
UnlistedProxyConnector that links to another direction exit.
17332
17333
</div>
17334
17335
<!------------------->
17336
<div class=entry>
17337
17338
Integrated Stephen Granade's menu system (menus.t) with the main
17339
library.
17340
17341
</div>
17342
17343
<!------------------->
17344
<div class=entry>
17345
17346
Added an on-line adaptive hint system (hints.t).
17347
17348
</div>
17349
17350
<!------------------->
17351
<div class=entry>
17352
17353
Added the new class RestrictedContainer.  This is a Container
17354
specialization that makes it easy to define containers that only
17355
accept certain objects as contents.  In the basic implementation, the
17356
allowable objects are simply enumerated as a list of objects; but
17357
this can be easily overridden for other methods of determining which
17358
objects are allowed.
17359
17360
</div>
17361
<!------------------->
17362
<div class=entry>
17363
17364
Added the new class SingleContainer, and the associated new
17365
precondition objEmpty.  SingleContainer is a specialization of
17366
Container that only allows a single object to be in the container at
17367
a time; this is suitable for things like sockets and receptacles.
17368
SingleContainer places the objEmpty precondition on the PutIn action;
17369
the objEmpty precondition simply requires that the subject object is
17370
empty, and tries implicit TakeFrom actions on the contents to
17371
accomplish this.
17372
17373
</div>
17374
<!------------------->
17375
<div class=entry>
17376
17377
In en_us.t, changed typographicalOutputFilter.eosPattern to ignore
17378
any run of HTML tags between sentence-ending punctuation and a
17379
following space.
17380
17381
</div>
17382
<!------------------->
17383
<div class=entry>
17384
17385
The main implicit action processor now uses the more abstract
17386
"allowed in implicit" test on the verify results, rather than merely
17387
checking for "dangerous" results.  This will allow results flagged as
17388
"non-obvious" to cancel implied actions, as they should.  (A
17389
non-obvious command should never be done implicitly, because implicit
17390
commands are specifically for actions that are obvious intermediate
17391
steps toward the explicitly stated command.)
17392
17393
</div>
17394
<!------------------->
17395
<div class=entry>
17396
17397
Openable and Lockable have been cleaned up slightly.  A new class,
17398
Linkable, has been added for objects that can be paired in
17399
master/slave relationships; Openable and Lockable are now based on
17400
Linkable.  This removes some duplicated code for managing the
17401
masterObject relationship.  In initialization, Linkable checks for a
17402
master object loop (where each object points to the other as the
17403
master) and break such loops by arbitrarily selecting one as the
17404
master.  Also, we have reduced the number of times we have to refer
17405
to masterObject by relying on isOpen/isLocked/makeOpen/makeLocked to
17406
defer to the master.  Also, the initiallyOpen/initiallyLocked
17407
initializations are now handled in initializeThing() rather than in
17408
isOpen/isLocked.
17409
17410
<p>Another new class, BasicOpenable, provides the basic state
17411
management for openable objects (which can optionally be linked
17412
in pairs to maintain the same status across the pair) but doesn't
17413
provide any of the verb handling of Openable.  This can be used
17414
for objects that want to maintain open/closed state using the
17415
usual method names, but which don't respond to direct player
17416
open/close commands.
17417
17418
<p><b>IMPORTANT:</b> Objects based on Openable and Lockable must
17419
<b>not</b> initialize their open status with isOpen or their locked
17420
status with isLocked.  Instead, initialize the status with
17421
initiallyOpen and initiallyLocked, respectively.  Also, be sure
17422
you never set isOpen or isLocked directly; instead, call makeOpen()
17423
and makeLocked() to effect these status changes.
17424
17425
</div>
17426
<!------------------->
17427
<div class=entry>
17428
17429
Changed Passage slightly to rely on isOpen/etc more to manage the
17430
masterObject relationship.
17431
17432
</div>
17433
<!------------------->
17434
<div class=entry>
17435
17436
Added a parameter to Direction.defaultConnector() giving the location
17437
from which travel is being attempted.  This allows the direction to
17438
customize the default connector according to the type of location.
17439
17440
</div>
17441
<!------------------->
17442
<div class=entry>
17443
17444
Added a new property, isShipboard, to Thing.  By default, if we have
17445
a location, we use the location's isShipboard setting, otherwise we
17446
return nil.  Rooms aboard ships can set this to true to indicate that
17447
shipboard directions make sense here.
17448
17449
<p>In ShipboardDirection.defaultConnector, if the source location or
17450
any container has 'isShipboard' set to true, then we now use noTravel
17451
as the default connector rather than noShipTravel, as the latter is
17452
meant to convey that shipboard directions make no sense in
17453
non-shipboard locations.
17454
17455
<p>Added a ShipboardRoom mix-in class that defines isShipboard to true.
17456
17457
</div>
17458
<!------------------->
17459
<div class=entry>
17460
17461
Changed the way that VerifyResultList determines if an action is
17462
allowed at all or allowed as an implicit command.  In the past, this
17463
calculation did what the "most disapproving" result in the list said
17464
to do; this wasn't quite right, because approval is essentially a
17465
separate axis from the "disapproval" order, despite the name.  In
17466
reality, the "disapproval" order is the message priority order, and
17467
the actual determination of approval depends on there being
17468
no disapprovers.  So, to determine approval, we now scan the full
17469
result list and require that every result approves; a single
17470
disapproval, no matter where it appears in message priority order,
17471
constitutes disapproval.
17472
17473
</div>
17474
<!------------------->
17475
<div class=entry>
17476
17477
In the English module, added a new token type for numbers specified
17478
with a leading pound sign (as in "#2 pencil" or "room #101").  These
17479
are treated essentially the same as numeric adjectives.  These match
17480
vocabulary for just the underlying numbers, not including the pound
17481
signs, so vocabulary should be specified simply as '2 pencil' and
17482
'101 room'.  (In other words, do <b>not</b> include a pound sign in
17483
vocabulary words; just use the number as with ordinary numeric
17484
adjectives, and the parser will match the number with or without the
17485
pound sign).
17486
17487
</div>
17488
<!------------------->
17489
<div class=entry>
17490
17491
The TravelVia check() condition in Passage no longer uses isOpen as
17492
its test.  Instead, it calls the new abstract condition method,
17493
canActorTravel(), passing the current actor as a parameter.  This
17494
makes it easy to allow some actors to pass and not others, and to
17495
test for conditions other than isOpen.  By default, canActorTravel()
17496
simply returns isOpen, so this doesn't change the default behavior.
17497
17498
<p>Along the same lines, Door.connectorTravelPreCond() now calls
17499
a separate method, getDoorOpenPreCond(), to obtain the door-is-open
17500
precondition object.  By default, this returns a doorOpen precondition
17501
(wrapped with an ObjectPreCondition for 'self'), so the default behavior
17502
hasn't changed.
17503
17504
</div>
17505
<!------------------->
17506
<div class=entry>
17507
17508
In the past, when an NPC was following another actor, and the actor
17509
being followed moved into a nested room within the current room, we
17510
generated a redundant message:
17511
17512
<p><pre>&gt;stand on platform
17513
Okay, you are now standing on the platform.
17514
Bill stands on the platform.
17515
Bill follows you onto the platform.
17516
</pre>
17517
17518
<p>
17519
The redundant "Bill follows you" has been eliminated.
17520
17521
</div>
17522
<!------------------->
17523
<div class=entry>
17524
17525
The reporting mechanism now processes sets of implicit action announcements
17526
to make them more readable and more easily understood.  In the past,
17527
each implicit action was shown separately; when one implicit action
17528
triggered another, this could make for somewhat confusing displays.
17529
For example, in the Platform Room in sample.t, if the PC is sitting on
17530
the blue chair and wants to get up and sit on the red chair, we formerly
17531
generated a transcript like this:
17532
17533
<p><pre>&gt;sit on red chair
17534
(first standing on the red platform)
17535
(first getting off of the blue platform)
17536
(first standing)
17537
Okay, you're now sitting on the red chair.
17538
</pre>
17539
17540
<p>To the uninitiated, this looks backwards: shouldn't we stand up,
17541
then get off the blue platform, then get on the red platform, and then
17542
sit on the red chair?  Of course, that's what's actually happening,
17543
and in its own way the transcript above reflects this: the second
17544
"first" applies to the first "first": it's saying "before you can
17545
stand on the red platform, you first have to get off the blue
17546
platform."  Likewise, the third "first" applies to the second "first,"
17547
to say "before you can stand on the red platform, you have to stand up
17548
first."  In other words, the implied reports are nested recursively.
17549
The recursive structure isn't represented visually, though, so it's
17550
not evident whether one of the later "firsts" refers to the preceding
17551
"first" or back to the original command line.  It would have been
17552
possible to represent the recursive structure visually, using
17553
indentation or something like that, but this probably wouldn't have
17554
made most people very happy; most non-programmers aren't accustomed to
17555
thinking in terms of recursion and stacks and tree views, and even
17556
programmers might well have found this kind of presentation to be too
17557
obviously mechanistic.
17558
17559
<p>To improve the situation, the transcript processor now features a
17560
new transform, called implicitGroupTransform, that rearranges these
17561
recursive listings into an order that should be entirely
17562
straightforward to anyone, programmer or not.  The new transform also
17563
consolidates these lists into a much more concise and readable format.
17564
The transformer does two things.  First, it "unstacks" recursive lists
17565
of implied action announcements to put them into the chronological
17566
order in which the commands were actually performed; the transcript
17567
has always kept track internally of which announcement is tied to
17568
which action, so the new transformer can merely inspect these records
17569
to determine the action relationships and use this information to
17570
unwind the stack.  Second, the transformer combines each run of
17571
adjacent implied action announcements into a single announcement,
17572
showing a list of the actions performed.  The result is that the
17573
example above now looks like this:
17574
17575
<p><pre>&gt;sit on red chair
17576
(first standing, getting off of the blue platform, then standing on
17577
the red platform)
17578
Okay, you're now sitting on the red chair.
17579
</pre>
17580
17581
<p>This new format should be easier for players to understand,
17582
since it shows implied actions in the order in which they're actually
17583
carried out, eliminating any need to be aware of the recursive
17584
goal-seeking work that the system is doing internally.  Hopefully,
17585
players will also find it more readable and less obviously mechanistic
17586
than the old format.
17587
17588
</div>
17589
17590
17591
<!------------------------------- 3.0.6a-e --------------------------------->
17592
<div class="sepbar"><a name='306ae'></a>3.0.6a-e</div>
17593
17594
<p><b><i>3.0.6e was released March 16, 2003</i></b>
17595
<p>
17596
17597
<div class=firstentry>
17598
17599
For a restore-on-startup operation, if the restore fails, don't simply
17600
start the game from the beginning.  Instead, offer options to START
17601
from the beginning, RESTORE another game, or QUIT, using the same type
17602
of prompt that we use for presenting "finishing" options.
17603
17604
</div>
17605
17606
<!------------------->
17607
<div class=entry>
17608
17609
Add a verb for OOPS typed at arbitrary times, which simply explains
17610
that OOPS can only be used after the parser has pointed out an unknown
17611
word.
17612
17613
</div>
17614
17615
<!------------------->
17616
<div class=entry>
17617
17618
Fix problem using possessive qualifiers in topic phrases.  (The
17619
problem is that we're using the topic resolver to resolve qualifiers
17620
in the topic phrase; we should be using an ordinary object resolver.
17621
Change the topic resolver's qualifier resolver to use the topic
17622
action's direct object resolver by default.)
17623
17624
</div>
17625
17626
<!------------------->
17627
<div class=entry>
17628
17629
Move the pronoun-setting routines (setPronoun, setIt, setHim, setHer,
17630
setThem) into Actor - these shouldn't be global functions since they
17631
need to operate on the current actor.
17632
17633
</div>
17634
17635
<!------------------->
17636
<div class=entry>
17637
17638
In TopicAction, set the pronoun antecedent based on the direct object
17639
phrase immediately during resolution, to allow things like "ask bob
17640
about his book."
17641
17642
</div>
17643
17644
<!------------------->
17645
<div class=entry>
17646
17647
Add a DefineIAction macro, for defining IAction classes.
17648
17649
</div>
17650
17651
<!------------------->
17652
<div class=entry>
17653
17654
Base LiteralAction on IAction, not directly on Action.
17655
17656
Because of this change, rewrite OopsAction to implement its processing
17657
in execAction() rather than doActionMain().
17658
17659
</div>
17660
17661
<!------------------->
17662
<div class=entry>
17663
17664
Refactor the Instructions action into an InstructionsAction base class
17665
and a separate grammar rule, to allow the base class to be referenced
17666
by name from other code.
17667
17668
</div>
17669
17670
<!------------------->
17671
<div class=entry>
17672
17673
Add a banner manager, along the lines of the input and output
17674
managers.  A new BannerWindow class would represent a banner; this
17675
would encapsulate the system banner handle and provide methods that
17676
operate on the banner.  The game should use the BannerWindow methods
17677
to perform all operations on banners, rather than calling the
17678
system-level banner API directly.
17679
17680
The banner manager should provide persistence support, so that the
17681
on-screen banner layout is restored on RESTORE, UNDO, or RESTART.  To
17682
this end, BannerWindow should be an ordinary persistent object, and a
17683
separate set of transient objects should track the current UI state.
17684
On RESTORE, UNDO, or RESTART, the transient tracking list and the
17685
persistent BannerWindow states should be compared, and the actual
17686
on-screen UI state, as represented in the transient objects, should be
17687
brought into line with the saved state.
17688
17689
</div>
17690
17691
<!------------------->
17692
<div class=entry>
17693
17694
Wait to mark an object as 'seen' in Thing.lookAroundWithin() until
17695
just before the method returns, so that any routines called from the
17696
method can check the old 'seen' status.
17697
17698
</div>
17699
17700
<!------------------->
17701
<div class=entry>
17702
17703
Fix gAction reference in Actor.travelWithin() so that it's conditional
17704
on gAction being non-nil.
17705
17706
</div>
17707
17708
<!------------------->
17709
<div class=entry>
17710
17711
Fix takeFromNotInActor message (iobj/dobj are reversed).
17712
17713
</div>
17714
17715
<!------------------->
17716
<div class=entry>
17717
17718
Fix TAction.retryWithMissingDobj() and
17719
TIAction.retryWithMissingIobj() so that they cancel the game time
17720
contribution of their enclosing (replaced) actions.
17721
17722
</div>
17723
17724
<!------------------->
17725
<div class=entry>
17726
17727
Fix touchObj precondition logic so that it realizes when an attempt
17728
to remove an obstruction with a precondition fails.  To do this, keep
17729
track of which obstructions we've tried to remove with implicit
17730
commands, and give up if we encounter the same obstruction more than
17731
once.
17732
17733
</div>
17734
17735
<!------------------->
17736
<div class=entry>
17737
17738
Add &lt;.parser> to msg_neu.t responses for some system verbs (NOTIFY
17739
ON/OFF, EXITS ON/OFF, a few others).
17740
17741
</div>
17742
17743
<!------------------->
17744
<div class=entry>
17745
17746
Assign the IndirectObject role to the literal in a LiteralTAction by
17747
overriding getRoleFromIndex, getObjectForRole, and getMatchForRole.
17748
These are needed to allow remapTo to be used with a LiteralTAction.
17749
17750
<p>
17751
Note that the literal is <b>always</b> in the IndirectObject role,
17752
regardless of whichLiteral, which only specifies the grammatical role
17753
for message generation purposes.
17754
17755
<p>
17756
Likewise, assign the IndirectObject role to the topic in TopicAction.
17757
This will allow remapTo to be used with a TopicAction.
17758
17759
</div>
17760
17761
<!------------------->
17762
<div class=entry>
17763
17764
Rename TopicAction to TopicTAction, parallel to LiteralTAction.
17765
17766
</div>
17767
17768
<!------------------->
17769
<div class=entry>
17770
17771
Add a new TopicAction that takes only a topic as its object, parallel
17772
to LiteralAction.
17773
17774
</div>
17775
17776
<!------------------->
17777
<div class=entry>
17778
17779
Rename whichObject, whichLiteral, and whichTopic to
17780
whichMessageObject, whichMessageLiteral, and whichMessageTopic,
17781
respectively, to make it clearer that these apply only to the roles
17782
played in generated messages, and not to any other roles.
17783
17784
<p>
17785
In particular, the message role only affects the way the object is
17786
used in generating messages based on the verb, such as "what do you
17787
want to open it with?".
17788
17789
</div>
17790
17791
<!------------------->
17792
<div class=entry>
17793
17794
It would be better to interpret "type on typewriter" as having a
17795
missing literal than as having a missing ON phrase (in other words,
17796
we want to interpreter this as TYPE &lt;empty literal&gt; ON TYPEWRITER
17797
rather than as TYPE "ON TYPEWRITER" &lt;on missing object&gt;).  
17798
17799
<p>
17800
To do this, add a verb rule for TYPE ON &lt;object&gt;, without any literal
17801
phrase.  For most objects, fail in verification; but when
17802
verification passes, in the action, ask for a missing literal phrase.
17803
(This has the additional benefit that it makes it easy to create
17804
objects that allow generic typing on them, as in TYPE ON COMPUTER,
17805
for situations where the game doesn't want to make the player type
17806
anything specific but still wants to allow the generic act of typing
17807
on the object.)
17808
17809
</div>
17810
17811
<!------------------->
17812
<div class=entry>
17813
17814
<pre>
17815
>ASK BOB ABOUT
17816
what do you want to ask him about?
17817
17818
>BILL
17819
"Ah, yes, , very interesting..."
17820
</pre>
17821
17822
<p>
17823
(The problem is that we're not propagating getOrigText() from the
17824
empty topic phrase match down to the underlying replacement match.)
17825
17826
</div>
17827
17828
<!------------------->
17829
<div class=entry>
17830
17831
<pre>
17832
>ASK BOB
17833
what do you want to ask him about?
17834
17835
>ABOUT BILL
17836
"Ah, yes, about bill, very interesting..."
17837
</pre>
17838
17839
<p>
17840
(The problem is that we need an aboutTopicPhrase production to parse
17841
responses to ABOUT WHAT questions.)
17842
17843
</div>
17844
17845
<!------------------->
17846
<div class=entry>
17847
17848
Add a generic Settable class for things (such as dials) that can be
17849
set to various settings.  Base Dial on Settable.
17850
17851
</div>
17852
17853
<!------------------->
17854
<div class=entry>
17855
17856
Do not override lookAroundWithinDesc() in BasicLocation; instead,
17857
provide an implementation of BasicLocation.roomDesc that simply uses
17858
the 'desc' property to display the room's interior description.
17859
(This allows nested rooms to differentiate more easily between
17860
interior and exterior descriptions, if they want to.)
17861
17862
</div>
17863
17864
<!------------------->
17865
<div class=entry>
17866
17867
Add a new method to Thing, filterResolveList(), to allow "global"
17868
filtering of a noun phrase resolution list.  Call this method from
17869
the parser where we use 'verify' to filter a resolution list.  Unlike
17870
'verify', this new method has access to the entire resolution list;
17871
this allows the method to take action based on which other objects
17872
are in the resolve list.
17873
17874
</div>
17875
17876
<!------------------->
17877
<div class=entry>
17878
17879
Add a new mix-in class, Collective, to serve the purpose of the
17880
former isCollectiveFor(obj) method in Thing.  To create an object
17881
like the matchbook in the sample game, use Collective as an
17882
additional base class.
17883
17884
<p>
17885
Remove the special-cased plural filtering in AllPluralProd and
17886
DefinitePluralProd.  Move this logic instead into Collective's
17887
filterResolveList() implementation.
17888
17889
</div>
17890
17891
<!------------------->
17892
<div class=entry>
17893
17894
Add a new class, CollectiveGroup, to allow creating "abstract"
17895
collective objects.  These differ from regular Collective objects in
17896
that a Collective is actually a simulation object (such as a
17897
matchbook that can hold several matches), whereas a CollectiveGroup
17898
is not a separate object from the player's perspective (so it's never
17899
listed as a separate object in a room's contents listing, for
17900
example).
17901
17902
<p>
17903
Add a new Thing property, collectiveGroup, that allows an ordinary
17904
object to be associated with a CollectiveGroup object.  In
17905
CollectiveGroup's filterResolveList() method, choose to keep either
17906
the individuals (the ordinary Thing objects associated via their
17907
collectiveGroup properties with a CollectiveGroup object) or the
17908
CollectiveGroup in the resolution list, but not both.  By default,
17909
make the selection based on action; subclasses can override as
17910
desired to use other criteria.
17911
17912
<p>
17913
CollectiveGroup can be used to create things like a "money" object
17914
to represent a set of coins and bills, so that a command like "look
17915
at money" can respond with a single description of all of the money
17916
present, rather than iterating over all of the coins and bills
17917
individually.
17918
17919
</div>
17920
17921
<!------------------->
17922
<div class=entry>
17923
17924
Eliminate the actorHereLister.  Instead, handle actor descriptions
17925
using the special description mechanism.  By default, give actors
17926
a higher specialDescOrder, to keep actor special descriptions listed
17927
after other special descriptions.
17928
17929
</div>
17930
17931
<!------------------->
17932
<div class=entry>
17933
17934
Add a new special description control property to Thing,
17935
specialDescBeforeContents; set it to true by default in Thing, but
17936
override it to nil in Actor.  In verbose room descriptions, show
17937
special descriptions in two phases: where we currently show special
17938
descriptions, just before the room's list of portable contents, show
17939
special descriptions only for items with specialDescBeforeContents
17940
set to true.  Then, after we've shown the portable contents list
17941
and any other sensory messages (listen/smell), show the special
17942
descriptions for objects with specialDescBeforeContents set to nil.
17943
17944
<p>
17945
This will allow the traditional ordering, with actor "I am here"
17946
messages placed after the rest of the room description, while keeping
17947
the rest of the special descriptions grouped with the room's main
17948
description.  Most special descriptions belong with the main room
17949
description because they're meant to be extensions of the room
17950
description.  Some special descriptions are not; they're meant to
17951
describe more ephemeral status information, so work better when
17952
grouped with the other status-like messages.  Actors in particular
17953
fall into the latter category, since actors are meant to seem
17954
autonomous, not parts of the rooms they occupy.
17955
17956
</div>
17957
17958
<!------------------->
17959
<div class=entry>
17960
17961
When showing special descriptions of the contents of an object as part
17962
of the object's description, use a new form of the special description
17963
method, showSpecialDescInContentsWithInfo(), and corresponding
17964
specific methods for viewing conditions (showSpecialDescInContents,
17965
showObscuredSpecialDescInContents, showDistantSpecialDescInContents).
17966
17967
<p>
17968
Override showSpecialDescInContents in Actor, so that we can show
17969
the type of description we previously showed using nestedActorLister.
17970
17971
<p>
17972
Remove nestedActorLister and NestedRoom.examineNestedRoomActors().
17973
17974
</div>
17975
17976
<!------------------->
17977
<div class=entry>
17978
17979
Add a default output filter, typographicalOutputFilter, to the main
17980
output stream.  In this filter, convert '--' and '---' sequences to
17981
typographical dashes, and insert an en space at the end of each
17982
sentence.
17983
17984
<p>
17985
The conversion of sentence-ending punctuation compensates for the
17986
elimination of the double-space insertion in the VM-level formatter.
17987
It also improves matters over the old way by making the treatment of
17988
sentence-ending punctuation customizable: the game can replace the
17989
filter method with its own custom conversions.  This allows
17990
customization not only for stylistic variation but for
17991
language-specific conventions as well.
17992
17993
</div>
17994
17995
<!------------------->
17996
<div class=entry>
17997
17998
Add the special {subj} messageBuilder token.  This token simply notes
17999
its target object as the subject of the sentence, for internal
18000
book-keeping purposes, but doesn't actually display anything.
18001
18002
</div>
18003
18004
<!------------------->
18005
<div class=entry>
18006
18007
Add a "log file console" type.  This would act like the main console
18008
or a banner console, in that it would apply the full set of VM-level
18009
output formatting (including text-only HTML interpretation) to the
18010
text sent through the stream, but it would write the output only to a
18011
file, rather than displaying it anywhere.  This would be useful for
18012
capturing output to a file without showing the output at all on the
18013
display; for example, this would make it easy to generate an About.txt
18014
file by capturing the output of the ABOUT command to a file during
18015
preinit, without having the ABOUT output also show up on the screen.
18016
18017
<p>
18018
This would require a new set of VM-level functions in the tads-io set:
18019
18020
<p> 
18021
<ul> 
18022
<li>logConsoleCreate(filename, charmap, width):
18023
returns a handle to the new console
18024
18025
<li>logConsoleSay(handle, ...): writes the arguments to the
18026
log console; works like say() and bannerSay()
18027
18028
<li>logConsoleClose(handle): closes the console
18029
</ul>
18030
18031
<p>
18032
In addition, add a LogConsole library class to simplify operations
18033
with the log console.  This class can be quite simple; it's just an
18034
OutputStream subclass that implements the writeFromStream method to
18035
call logConsoleSay().
18036
18037
</div>
18038
18039
<!------------------->
18040
<div class=entry>
18041
18042
Add a TopicQualifierResolver subclass of Resolver, specifically for
18043
resolving qualifier phrases in topics.  Use a new instance of this
18044
class instead of the direct object resolver in TopicActionBase.  (The
18045
direct object resolver isn't really appropriate, and doesn't work at
18046
all with plain TopicActions, because they don't have direct object
18047
resolvers at all.)
18048
18049
</div>
18050
18051
<!------------------->
18052
<div class=entry>
18053
18054
Add a new mapping macro, iobjAsDobjFor(), that makes it safe to map
18055
an indirect object handler to a direct object handler in the same
18056
object.  Use this for the mapPushTravelHandlers() macro.
18057
18058
<p>
18059
(The mapPushTravelHandlers() macro essentially wants to decompose the
18060
two-object action into two single-object actions, which isn't safe
18061
with the regular asDobjFor() mapping.  The difference with
18062
iobjAsDobjFor() is that this new routine temporarily makes the
18063
indirect object take on the direct object role, so that the target
18064
dobj handler sees the proper object in the direct object slot.)
18065
18066
</div>
18067
18068
<!------------------->
18069
<div class=entry>
18070
18071
Add a LabeledDial subclass of Dial.  This class accepts arbitrary text
18072
labels as dial stops; the property validSettings contains a list of
18073
strings giving the valid dial stop labels.
18074
18075
</div>
18076
18077
<!------------------->
18078
<div class=entry>
18079
18080
Remove any .t and .tl extensions from adv3.tl and en_us.tl.  (The
18081
extensions are implied by the file types; it makes the library file
18082
more portable to omit the extensions, since the compiler will
18083
automatically apply the default extensions using the appropriate local
18084
conventions when the extensions aren't explicitly included in the
18085
names as they appear in the library files.)
18086
18087
</div>
18088
18089
<!------------------->
18090
<div class=entry>
18091
18092
Get rid of Thing.articleIndef; games should simply override aName
18093
instead when they want to override the default indefinite article
18094
determination.
18095
18096
</div>
18097
18098
<!------------------->
18099
<div class=entry>
18100
18101
Change the way theDisambigName, aDisambigName, and countDisambigName
18102
work.  If name == disambigName, then return the corresponding xxxName
18103
from xxxDisambigName; otherwise, apply the same algorithm to
18104
disambigName that the corresponding xxxName applies to name.  For
18105
example, in aDisambigName, if name == disambigName, simply return
18106
aName; otherwise, apply the indefinite article algorithm to
18107
disambigName and return the result.
18108
18109
<p>
18110
This change will allow disambigName to be overridden without
18111
requiring all of the xxxDisambigName's to be overridden at the same
18112
time, because the xxxDisambigName's will by default apply the
18113
standard algorithms to the modified disambigName.  At the same time,
18114
though, this has the virtue of the original implementation that, in
18115
the common case where disambigName is not overridden, any overrides
18116
to theName, aName, and countName will be used for the corresponding
18117
xxxDisambigName's.  Furthermore, since these are all still separate
18118
methods, objects can still separately override each xxxDisambigName
18119
as needed for cases where the disambigName is customized <i>and</i> the
18120
customized name requires overriding the normal article algorithms.
18121
18122
<p>
18123
While we're at it, add pluralDisambigName, using the same logic.
18124
18125
</div>
18126
18127
<!------------------->
18128
<div class=entry>
18129
18130
Remove the dictionary properties possessiveAdj, possessiveNoun, and
18131
their corresponding grammar.  (These are no longer needed, since we
18132
now have explicit grammar for all of the possessive pronouns in
18133
adjective and noun usages.  At one time, these were used for adding
18134
vocabulary for the player character, but it worked better to use the
18135
grammar and resolver mechanism more explicitly.)
18136
18137
</div>
18138
18139
<!------------------->
18140
<div class=entry>
18141
18142
Rework "'s" handling for literal vocabulary:
18143
18144
<p>
18145
First, remove the special-case tokenizer handling for "'s" words that
18146
appear in the dictionary, so that we handle <b>all</b> "'s" words
18147
uniformly in the tokenizer: all "'s" suffixes are treated as separate
18148
tokens.
18149
18150
<p>
18151
Second, never add "'s" words to the dictionary in initializeVocab().
18152
Instead, define a new dictionary property, adjApostS; when we see a
18153
"'s" word in a vocabulary list, remove the "'s" suffix and add only
18154
the prefix to the dictionary, but add it as an adjApostS instead of
18155
as an adjective.  (For simplicity, don't bother with nounApostS at
18156
all; allow only adjectives as apostrophe-s words.)
18157
18158
<p>
18159
Third, add a new grammar production, adjWord, that accepts either a
18160
single adjective or an adjApostS followed by an apostrophe-s token.
18161
18162
<p>
18163
Fourth, where appropriate, change 'adjective->' grammar rules to use
18164
'adjWord->' instead.
18165
18166
<p>
18167
These changes correct the problem that adding a literal "'s" word to
18168
an object's vocabulary prevented that word from being used as a true
18169
possessive phrase in the grammar.  The old tokenizer rule was that a
18170
word that appeared with an explicit "'s" suffix in the dictionary was
18171
kept intact, rather than split into separate tokens for the root word
18172
and the "'s" suffix.  Since the word was kept intact as a single
18173
token, it couldn't match the grammar rules for possessive phrases,
18174
which only match the separated form.  These changes allow the same
18175
word to be used in either context, since everything is treated the
18176
same way in the tokenizer; even if a word is used as a literal
18177
vocabulary word with a "'s", it'll still be split up during
18178
tokenization.  Even with this change, we can still match explicit
18179
"'s" vocabulary words, thanks to the adjWord grammar.
18180
18181
<p>
18182
Note this has one small potential impact on existing games: if an
18183
object explicitly defines its own 'adjective' property (rather than
18184
using the automatic library initialization), and a word defined in the
18185
adjective list ends in apostrophe-s, then that word must be stripped
18186
of the apostrophe-s suffix, removed from the 'adjective' list, and
18187
added to a new 'adjApostS' list instead.  Similarly, if any vocabulary
18188
words that end in apostrophe-s are dynamically added with
18189
G_dict.addWord(), the apostrophe-s words should be stripped of the
18190
suffix and added under the '&adjApostS' property instead of the
18191
'&adjective' property.
18192
18193
</div>
18194
18195
<!------------------->
18196
<div class=entry>
18197
18198
Add noteLiteral(lst_.getOrigText()) to getVocabMatchList() in
18199
simpleNounPhrase(misc)?  This would make the length of text in a
18200
miscellaneous word list a match selection criterion (less important
18201
than the presence of a misc word list).  This won't change anything in
18202
cases where we want to choose between a match with a misc word list
18203
and one without, as the presence or absence of a misc word list is
18204
more important than literal length, but it will help distinguish
18205
between two matches that both have misc word lists.  Since we prefer a
18206
shorter literal match, this will have the effect of preferring to
18207
match the more structured interpretation, since a shorter misc word
18208
match means a longer grammar match.
18209
18210
</div>
18211
18212
<!------------------->
18213
<div class=entry>
18214
18215
Fix run-time error with "a <phrase>" (the 'inherited' argument list
18216
is wrong in AskAboutAction.getDefaultDobj; the same problem is in
18217
TellAboutAction).
18218
18219
</div>
18220
18221
<!------------------->
18222
<div class=entry>
18223
18224
Rename class Fixed to Fixture.
18225
18226
</div>
18227
18228
<!------------------->
18229
<div class=entry>
18230
18231
Add new class Immovable: this is for objects that aren't fixed in
18232
place obviously or by their very nature (as are Fixtures), but rather
18233
are fixed for some other reason: great weight, hidden fasteners, etc.
18234
This class differs from Fixture in that it disallows actions like
18235
take, move, push, and pull not in the verify() but in the action().
18236
18237
<p>
18238
Add a subclass, Heavy, for objects that are immovable because they're
18239
very heavy.  This is suitable for things like large furniture and big
18240
boulders.
18241
18242
</div>
18243
18244
<!------------------->
18245
<div class=entry>
18246
18247
Remove moveInto() override on Immovable.  (This attempted to be a last
18248
resort to disallow actions that involved trying to move the object,
18249
but it prevented programmatic relocation as well, creating more
18250
problems than it solved.)
18251
18252
</div>
18253
18254
<!------------------->
18255
<div class=entry>
18256
18257
Fix problem with applying AGAIN to a command issued to another actor:
18258
the target actor becomes "busy" and won't accept another command until
18259
a turn passes.  The problem is that we're not accounting for
18260
synchronous actors in the AGAIN processing: we need to tell the issuer
18261
to waitForIssuedCommand on the target actor.
18262
18263
</div>
18264
18265
<!------------------->
18266
<div class=entry>
18267
18268
Fix problem in GiveTo and ShowTo actions: getDefaultIobj calls
18269
inherited() with wrong argument list.
18270
18271
</div>
18272
18273
<!------------------->
18274
<div class=entry>
18275
18276
Fix the parameter list for npcActionMessages.okayTurnTo.
18277
18278
</div>
18279
18280
<!------------------->
18281
<div class=entry>
18282
18283
Make RandomTextList customizable with the percentage of the time a
18284
message is generated at all.  Random message lists are often used for
18285
atmospheric messages, and it's usually better if these messages don't
18286
appear on every single turn.  Add a 'messagePercent' property that
18287
determines the percentage of turns where a message is generated; the
18288
default is 100, which leaves the default behavior as it was (i.e., a
18289
message is generated on every turn).
18290
18291
<p>
18292
In addition, especially with random atmospheric messages, it can get
18293
tedious to see the same messages over and over if you spend a lot of
18294
time in the same area.  It's therefore often the case that we want
18295
frequent atmospheric messages when the player first gets to a
18296
location, but then we want the frequency to drop dramatically after
18297
the player has spent more than a few turns there.  To make this easy
18298
to handle, add a couple of new properties: 'messageReduceAfter' is the
18299
number of times that we want to see messages at the initial frequency,
18300
and 'messageReduceTo' is a new value for 'messagePercent' that we'll
18301
apply after we've generated the messages 'messageReduceAfter' times.
18302
Make these nil by default, which means that there is never a reduction
18303
in the frequency.  Authors can use these properties to generate random
18304
atmosphere messages at high frequency at first, but then drop the
18305
frequency to just an occasional message after the player has been in
18306
the location long enough to get the idea.
18307
18308
</div>
18309
18310
<!------------------->
18311
<div class=entry>
18312
18313
Add a new class, NominalPlatform.  This is a "secret" object: it's not
18314
visible to the player as a separate simulation object, and won't
18315
normally have any vocabulary or appear in any room listings.  The
18316
purpose of this object is to make it easier to describe NPC's as
18317
standing somewhere specific within a room; the author locates an NPC
18318
within the NominalPlatform, and the library will automatically
18319
describe the NPC as standing on the platform: "Bob is here, standing
18320
in the corner."  The author can also customize the display methods for
18321
the nominal platform so that the description is something like
18322
"leaning against the lamppost."
18323
18324
</div>
18325
18326
<!------------------->
18327
<div class=entry>
18328
18329
Add a new property to Thing, specialContentsLister, that lets
18330
individual objects and rooms customize the lister they use to generate
18331
special descriptions.  Set the property by default to
18332
specialDescLister.
18333
18334
</div>
18335
18336
<!------------------->
18337
<div class=entry>
18338
18339
Add a new topicPhrase grammar rule that matches a miscWordList without
18340
badness.  (The normal topicPhrase grammar matches a singleNoun, which
18341
matches a miscWordList, but it does so with badness; we want to add an
18342
explicit rule that matches a miscWordList without badness.)  It's in
18343
the nature of topic phrases to go outside of what's implemented in the
18344
simulation model; we don't want to treat resolvable and irresolvable
18345
topic phrases any differently at the grammatical level, because doing
18346
so can lead to inconsistencies when parsing a verb containing both a
18347
topic and another kind of noun phrase.
18348
18349
</div>
18350
18351
<!------------------->
18352
<div class=entry>
18353
18354
Add gLiteral to adv3.h, analogous to gTopic.
18355
18356
</div>
18357
18358
<!------------------->
18359
<div class=entry>
18360
18361
Change Thing.dobjFor(Attack) so that the default Attack handling is
18362
simply to display the message "it's useless to attack that."  Remove
18363
the askIobjFor(AttackWith).  Specifying a weapon shouldn't be
18364
required; especially for attacks like "hit" and "kick," asking for an
18365
indirect object will seem wrong to a player.  This makes a tiny bit of
18366
extra work for authors when AttackWith is overridden, since Attack
18367
will have to be overridden as well in such cases, but this is probably
18368
worthwhile anyway because it'll encourage authors to make the same
18369
distinction between weapon and weaponless attacks that players are
18370
likely to make in their own minds.
18371
18372
</div>
18373
18374
<!------------------->
18375
<div class=entry>
18376
18377
Move the code from Contents.examineContainerContents into
18378
Thing.examineStatus (actually, into a new method called from
18379
Thing.examineStatus, call it examineListContents).  Get rid of
18380
Surface.examineSurfaceContents.  Ordinary Thing objects should
18381
traverse into their contents during Examine; this shouldn't be limited
18382
to Container and Surface objects.  We need to do this listing in
18383
Thing, because a Thing could contain a component that's a container,
18384
and we want to list its contents when examining the Thing.
18385
18386
</div>
18387
18388
<!------------------->
18389
<div class=entry>
18390
18391
Fix bug in Action.getObjPreconditions: if pre is nil before appending
18392
the catch-all list, we'll get an error.  Check that pre is nil before
18393
appending, and just use the catch-all list by itself if so.
18394
18395
</div>
18396
18397
<!------------------->
18398
<div class=entry>
18399
18400
Change the TravelConnector.describeDeparture() and describeArrival()
18401
interfaces to add a new parameter for the traveler.  Use the traveler
18402
parameter instead of the global gActor.  This makes the travel
18403
routines more flexible, and in particular allows them to be called
18404
from outside of commands (in daemons, for example).  It also will
18405
improve the handling for non-actor travelers (vehicles in particular).
18406
18407
</div>
18408
18409
<!------------------->
18410
<div class=entry>
18411
18412
In RoomConnector.describeDeparture/Arrival, use gPlayerChar rather
18413
than gActor as the point-of-view object in directionForConnector().
18414
The description is being generated for the benefit of the player, so
18415
it should be from the PC's perspective.
18416
18417
<p>
18418
Split off a new method from each of Traveler.describeDeparture and
18419
describeArrival: describeNpcDeparture/Arrival, which is called when
18420
an NPC (or a traveler not involving the PC) is doing the travel.
18421
This will simplify overriding the messages for vehicles and other
18422
special travelers when desired, since the overriding method won't
18423
have to make all of the checks to see if it's the PC doing the travel.
18424
18425
</div>
18426
18427
<!------------------->
18428
<div class=entry>
18429
18430
Run all of the libMessages.sayDeparting/Arriving connector-specific
18431
messages through an intermediate method call in the Traveler; these
18432
new Traveler methods by default are simply be covers for calls to the
18433
libMessages methods.  The purpose of the extra layer of calls through
18434
Traveler is to make it easier for individual Traveler subclasses to
18435
customize the messages on a per-connector-subclass basis.
18436
18437
</div>
18438
18439
<!------------------->
18440
<div class=entry>
18441
18442
'@script.txt' at the command prompt should start reading from the
18443
named script file.  (This should work essentially the same way it did
18444
in tads 2, except that we want to handle this in the library instead
18445
of in the interpreter.)  Also, '@@script.txt' should run the script in
18446
"quiet mode," which is to say that input and output generated while
18447
reading the script are to be suppressed.
18448
18449
</div>
18450
18451
<!------------------->
18452
<div class=entry>
18453
18454
Add some new classes to misc.t for "shuffled" random selections.  A
18455
shuffled selection is a random selection taken from a set of values
18456
that doesn't repeat a selection until we've gone through all of the
18457
values once, like dealing from a shuffled deck of cards.
18458
18459
<p>
18460
ShuffledList: the basic shuffled selection class.  Keeps a list of
18461
values, and returns a randomly selected element on demand.
18462
18463
<p>
18464
ShuffledIntegerList: a specialization of ShuffledList that returns
18465
a randomly selected integer from a given range.
18466
18467
<p>
18468
ShuffledTextList: a subclass of RandomTextList that makes its
18469
selection using shuffling rather than independent random selection.
18470
18471
</div>
18472
18473
<!------------------->
18474
<div class=entry>
18475
18476
Add a point-of-view parameter to Thing.showSpecialDescWithInfo().
18477
18478
</div>
18479
18480
<!------------------->
18481
<div class=entry>
18482
18483
Add a parameter to the following library messages to indicate which
18484
object is being described (the object is needed for things like gender
18485
and number agreement in some languages):
18486
18487
<p>
18488
openMsg, closedMsg, lockedMsg, unlockedMsg, onMsg, offMsg
18489
18490
</div>
18491
18492
<!------------------->
18493
<div class=entry>
18494
18495
Add a parameter to the following library messages to indicate which
18496
actor is being described (the actor is needed for things like gender
18497
and number agreement in some languages):
18498
18499
<p>
18500
statusStanding, statusSitting, statusLying, 
18501
statusStandingOn, statusSittingOn, statusLyingOn
18502
18503
</div>
18504
18505
<!------------------->
18506
<div class=entry>
18507
18508
Add a parameter to the various name methods in ThingState (listName,
18509
inventoryName, wornName) providing a list of the objects being shown
18510
in this state.  This is needed for some languages so that the state
18511
description can agree (in gender and number, for example) with the
18512
objects being desribed as being in the state.
18513
18514
</div>
18515
18516
<!------------------->
18517
<div class=entry>
18518
18519
Change the count parameter to the full list in
18520
actorStandingGroupPrefix and the related methods in libMessages.
18521
This will allow the prefix/suffix messages to check any attributes of
18522
the individual objects in the list, such as gender mix, that might
18523
affect the message.
18524
18525
</div>
18526
18527
<!------------------->
18528
<div class=entry>
18529
18530
The INSTRUCTIONS command should not take any turns (make it a
18531
"system" command).  Also, it should not consume any game time on the
18532
real-time clock (which, given the size of the instructions, could be
18533
noticeable).
18534
18535
</div>
18536
18537
<!------------------->
18538
<div class=entry>
18539
18540
Add an extended form of inputManager.getInputLine(), which takes a
18541
new InputDef object to define the input parameters.  Use this new
18542
parameter definitions object to determine what to display to set and
18543
remove the input text style; do this instead of unconditionally using
18544
the <.inputline> style tag.  The InputDef class should use
18545
<.inputline> as the default, of course.  Keep the existing
18546
getInputLine() method, but make it a cover for a call to the new
18547
extended version, setting up an InputDef object representing the
18548
parameters.
18549
18550
</div>
18551
18552
<!------------------->
18553
<div class=entry>
18554
18555
Make "remove" (with a direct object but no indirect object) a fully
18556
separate verb from "doff".  In English, "remove foo" usually means
18557
"doff foo", but it can also have the substantially separate sense of
18558
removing a component of an object.  In the English library module,
18559
provide a default mapping of "remove" to "doff" in Thing, to keep the
18560
default meaning the same.  Making a separate Remove action will allow
18561
this action to be independently overridden per object when it's
18562
desirable to do so.
18563
18564
</div>
18565
18566
<!------------------->
18567
<div class=entry>
18568
18569
By default, don't list anything in the credits for a library module.
18570
We should leave the formatting of the credits fully up to the author.
18571
18572
</div>
18573
18574
<!------------------------------- 3.0.5 --------------------------------->
18575
<div class="sepbar"><a name='305'></a>3.0.5</div>
18576
18577
<div class=firstentry>
18578
18579
Add an optional mainRestore() function, to be provided by the game
18580
and called from the run-time startup code when a saved game is
18581
explicitly selected for restoration at startup (such as by
18582
double-clicking on a saved position file from a GUI desktop, or using
18583
the "-r" option with the command-line interpreter).
18584
18585
</div>
18586
18587
<!------------------->
18588
<div class=entry>
18589
18590
Change runGame() so that it no longer takes the initial player
18591
character parameter.  Instead, callers should always set gPlayerChar
18592
explicitly prior to calling runGame().  (This change makes runGame()
18593
more sensible for cases where a game is restored: since the restore
18594
operation will restore gPlayerChar as part of restoring the rest of
18595
the game's state, it would be redundant to pass gPlayerChar as a
18596
parameter to runGame() only to have runGame() set gPlayerChar to that
18597
value.)
18598
18599
</div>
18600
18601
<!------------------->
18602
<div class=entry>
18603
18604
Fix the bug in EventManager.removeMatchingEvents ('eventMatches' should 
18605
be 'cur.eventMatches')
18606
18607
</div>
18608
18609
<!------------------->
18610
<div class=entry>
18611
18612
Add a new output stream method, addOutputFilterBelow(), which adds an
18613
output filter at a given point in the filter stack.
18614
18615
</div>
18616
18617
<!------------------->
18618
<div class=entry>
18619
18620
Remove the "\( \)" escape sequences (for highlighted text).  Authors
18621
should use HTML markups <B> and </B> instead.
18622
18623
</div>
18624
18625
<!------------------->
18626
<div class=entry>
18627
18628
Combine open/closed and contents status listings into a single
18629
message, to make the openable container default description less
18630
choppy.
18631
18632
</div>
18633
18634
<!------------------->
18635
<div class=entry>
18636
18637
Rename maxBulk to bulkCapacity, to make the meaning clearer.
18638
Similarly, rename maxWeight to weightCapacity.
18639
18640
</div>
18641
18642
<!------------------->
18643
<div class=entry>
18644
18645
>put trike in bag. drop bag. ride trike.
18646
(produces a run-time error)
18647
18648
The problem is that we're failing to treat the bag as an invalid
18649
"staging location" on the way to boarding the trike.  Add a routine,
18650
checkStagingLocation, to Thing, and call when moving an actor into a
18651
chosen staging location; this routine should generate an error
18652
explaining why the travel is impossible and terminate the command
18653
with 'exit'.  BasicLocation should override this to allow being used
18654
as a staging location.
18655
18656
</div>
18657
18658
<!------------------->
18659
<div class=entry>
18660
18661
add default Thing handling for 'feel' and 'taste' commands
18662
18663
</div>
18664
18665
<!------------------->
18666
<div class=entry>
18667
18668
<pre>
18669
>close bag; x all in bag
18670
red ball: You cannot see that. [etc]
18671
</pre>
18672
<p>
18673
We're incorrectly resolving the contents of an object for an "all in
18674
x" phrase, even when the contents can't be seen.  We must filter the
18675
resolved objects to include only the visible contents.
18676
18677
</div>
18678
18679
<!------------------->
18680
<div class=entry>
18681
18682
"all in x" doesn't filter for objects hidden from "all" phrases; it
18683
should.
18684
18685
</div>
18686
18687
<!------------------->
18688
<div class=entry>
18689
18690
Standing should be a precondition of "jump".
18691
18692
</div>
18693
18694
<!------------------->
18695
<div class=entry>
18696
18697
The noMatchDisambig and disambigOrdinalOutOfRange messages should use
18698
<.parser> open tags, but not close tags: instead, the <.parser> mode
18699
should be left open, to be closed by the disambiguation re-prompt that
18700
always follows.
18701
18702
<p>
18703
askDisambig should provide an open <.parser> tag if and only if askAgain
18704
is false: this will let the mode flow in from the preceding re-prompt
18705
message from noMatchDisambig or disambigOrdinalOutOfRange.  askDisambig
18706
should always close the <.parser> tag.
18707
18708
</div>
18709
18710
<!------------------->
18711
<div class=entry>
18712
18713
Get rid of parserMessage(), and just use <.parser> tags instead.
18714
18715
</div>
18716
18717
<!------------------->
18718
<div class=entry>
18719
18720
We shouldn't be able to read at brightness 2.  For Readable,
18721
differentiate readability according to brightness and transparency,
18722
as long as a readDesc is defined.  (When no readDesc is defined for
18723
the object, use the default "examine" behavior as usual.)
18724
18725
</div>
18726
18727
<!------------------->
18728
<div class=entry>
18729
18730
Disambiguation: when indistinguishables are involved, answering with
18731
an ordinal applies the ordinal to the full list, rather than the
18732
reduced list offered:
18733
18734
<p><pre>
18735
>take coin
18736
Which coin do you mean, a gold coin, a silver coin, or a copper coin?
18737
18738
>second
18739
Taken. [actually takes a gold coin, since more than one was present]
18740
</pre>
18741
</div>
18742
18743
<!------------------->
18744
<div class=entry>
18745
18746
Add a new option flag, libGlobal.allowYouMeMixing, that controls
18747
whether or not the parser accepts "you" and "me" in commands as
18748
equivalent.  Set this to true by default, since most games will not
18749
have both first- and second-person narrative characters at the same
18750
time, and hence it seems unlikely that it will ever create confusion
18751
if the player can use "you" and "me" interchangeably.  (Having the
18752
option to make the parser strict about this will take care of any
18753
cases where a game actually does have separate first- and
18754
second-person characters present simultaneously.)
18755
18756
</div>
18757
18758
<!------------------->
18759
<div class=entry>
18760
18761
The forwarding scheme isn't quite right.  Replace it.
18762
18763
<p>
18764
First, get rid of dobjForwardTo, iobjForwardTo, remapTIAction,
18765
dobjRemapTI, iobjRemapTI, dobjRemapTIReverse, and iobjRemapTIReverse.
18766
18767
<p>
18768
Second, add a new mechanism that combines the old forwarding and
18769
remapping schemes into a single new system.  Use syntax like so:
18770
18771
<p><pre>
18772
desk: Fixed
18773
  dobjFor(Open) remapTo(Open, drawer)
18774
  dobjFor(Close) remapTo(Close, drawer)
18775
;
18776
</pre>
18777
<p>
18778
The first definition above maps the Open action, when applied to the
18779
desk, to a replacement action of Open applied to the drawer instead.
18780
The second does the same thing for Close.  This replaces the old
18781
dobjForwardTo/iobjForwardTo scheme, so we no longer need forwarding at
18782
all.  The difference with the new remapTo scheme is that we use a
18783
replacement action for the remapping - the remap for Open above is
18784
essentially like using replaceAction(Open, drawer) for the action
18785
definition of Open on the desk.
18786
18787
<p>
18788
Further, consider this syntax:
18789
18790
<p><pre>
18791
lid: Fixed
18792
  dobjFor(Push) remapTo(Open, jar)
18793
  dobjFor(Pull) remapTo(Close, jar)
18794
;
18795
</pre><p>
18796
Here we've remapped not only the object (as we formerly did with
18797
forwarding), but also the action.  The first definition above says
18798
to replace "push lid" with the new action "open jar."
18799
18800
<p>
18801
Next, consider this:
18802
18803
<p><pre>
18804
ninjaThrowingStar: Weapon
18805
  iobjFor(AttackWith) remapTo(ThrowAt, self, DirectObject)
18806
;
18807
</pre>
18808
<p>
18809
In this case, we're doing what the old dobjRemapTIReverse did, but
18810
with considerably clearer syntax.  We're saying that when we resolve
18811
the indirect object of "attack with" and find that it's the throwing
18812
star, we should remap the action to "throw <ninjaThrowingStar> at
18813
<direct object>", where <direct object> is the original direct object
18814
of the AttackWith action.  The important thing about using the
18815
"DirectObject" argument is that it tells us to use the pre-resolved
18816
match tree for the direct object if we haven't yet resolved the direct
18817
object noun phrase - this means that we'll be able to resolve that
18818
noun phrase in the context of the new action (ThrowAt) rather than in
18819
the original action (AttackWith) context.
18820
18821
</div>
18822
18823
<!------------------->
18824
<div class=entry>
18825
18826
Compiler: for each nested object definition, set a property of the
18827
nested object, 'lexicalParent', to point to the lexically enclosing
18828
object.
18829
18830
</div>
18831
18832
<!------------------->
18833
<div class=entry>
18834
18835
Change the default message for talking/asking/etc a random object to
18836
indicate more specifically that it's illogical to talk to the object.
18837
18838
</div>
18839
18840
<!------------------->
18841
<div class=entry>
18842
18843
Add a class for a complex container, for objects that contain objects
18844
in multiple ways.  Examples: a crate that can contain things within
18845
and also have objects placed on top of it; a container with
18846
components.
18847
18848
<p>
18849
The class should treat all of its immediate contents as components,
18850
so it should be based on Thing rather than Container or Surface.  It
18851
should have two additional properties: one for a secret object that
18852
serves as the internal container, and another for a secret object
18853
that serves as the internal surface.  Commands like "put in" and
18854
"look in" should be redirected to the internal container, if one is
18855
defined; "put on" and the like to the internal surface, if present.
18856
The contents lister must specifically show the contents of the secret
18857
internal container and surface as though they were contained directly
18858
by the outer object.
18859
18860
</div>
18861
18862
<!------------------->
18863
<div class=entry>
18864
18865
Change default Thing handling for Push, Pull, Move, MoveWith (dobj),
18866
and MoveTo (dobj), so that verification succeeds with a logicalRank
18867
of 50, and report that there is no effect in the action.  (These
18868
actions all involve physical manipulations that a player might want
18869
to try with any object, so it's better to allow these to pass
18870
verification, so that preconditions can be allowed to proceed rather
18871
than halting before even getting to preconditions.)
18872
18873
</div>
18874
18875
<!------------------->
18876
<div class=entry>
18877
18878
OutOfReach seems to put the object itself (not just its contents) out
18879
of reach.  Add a separate test for reaching 'self'.
18880
18881
</div>
18882
18883
<!------------------->
18884
<div class=entry>
18885
18886
In Actor.canReach, don't make touching our immediate location a special
18887
case - just traverse the sense path to the container as normal.
18888
18889
</div>
18890
18891
<!------------------->
18892
<div class=entry>
18893
18894
<pre>
18895
>look in stove
18896
(First opening the stove)
18897
Opening the stove reveals a loaf of bread.  The stove contains a loaf of bread.
18898
</pre>
18899
<p>
18900
It would be good to remove this redundancy: if we're opening
18901
something implicitly for a look-in command, we shouldn't bother
18902
showing what the opening reveals.  (We can handle this in Openable's
18903
Open action handler: if the action is implied, and the parent action
18904
is LookIn with the same direct object, we can suppress the revelation
18905
message.)
18906
18907
</div>
18908
18909
<!------------------->
18910
<div class=entry>
18911
18912
Suppress default "you see nothing special about it" or "it's an
18913
ordinary x" descriptions when there's a special status message,
18914
such as contents to be listed.
18915
18916
</div>
18917
18918
<!------------------->
18919
<div class=entry>
18920
18921
<pre>
18922
>look in small alcove
18923
You see nothing in it.  A trophy is visible...
18924
</pre>
18925
<p>
18926
(Perhaps if we special description items, and nothing listed, we should
18927
display no message at all.)
18928
18929
</div>
18930
18931
<!------------------->
18932
<div class=entry>
18933
18934
Use tags for line-input modes in commandSequencer, eliminating method
18935
calls.  This should remove the fragile order-of-call issues that we 
18936
currently have.
18937
18938
</div>
18939
18940
<!------------------->
18941
<div class=entry>
18942
18943
Should we reformat some messages involving implied commands?  For example:
18944
18945
<p><pre>
18946
>put coin in bag
18947
(first opening the bag)
18948
Opening the bag reveals a keyring. Done.
18949
</pre>
18950
<p>
18951
Perhaps we should put that "done" on a new line - no paragraph separator,
18952
just a new line.  (In general, perhaps when there's a non-default response
18953
from an implied command, we should add an "implied command terminator
18954
separator," which by default would simply be a newline.)
18955
18956
</div>
18957
18958
<!------------------->
18959
<div class=entry>
18960
18961
Rename the English-specific part of the library to make it easier to add
18962
new languages in the future.  In particular:
18963
18964
<ul>
18965
<li>Create a new US English subdirectory of the
18966
adv3 library directory; use ISO 639/3166 codes for the naming
18967
convention, so the US English directory is called en_us.
18968
18969
<li>Move us_eng.t to en_us/en_us.t
18970
18971
<li>Move us_eng.h to en_us/en_us.h
18972
18973
<li>Move msg_neu.t to en_us/msg_neu.t
18974
18975
<li>Add a new library, en_us/en_us.tl.  Move the
18976
English-specific source file inclusions out of adv3.tl and into
18977
en_us.tl.
18978
18979
<li>Include the new en_us.tl library in the
18980
auto-generated makefile for the new-project wizard in Workbench.
18981
(We'll have to add a user preference at some point that lets the user
18982
select the language library to use, rather than using en_us.tl
18983
unconditionally.) 
18984
 </ul>
18985
18986
</div>
18987
18988
<!------------------->
18989
<div class=entry>
18990
18991
Add a general IF instructions module (like instruct.t from tads 2)
18992
18993
</div>
18994
18995
<!------------------->
18996
<div class=entry>
18997
18998
Fix nil dereference in transcript processing for ambiguous noun
18999
phrase errors.
19000
19001
</div>
19002
19003
<!------------------->
19004
<div class=entry>
19005
19006
Fix command state management for suffixes so that suffixes are always
19007
generated before the prompt.  (We simply need to display <.commandbegin>
19008
in intput.t before displaying the prompt.)
19009
19010
</div>
19011
19012
<!------------------->
19013
<div class=entry>
19014
19015
Add a new command state, stateNoCommand, for interactive input.  In
19016
this state, don't add any prefixes/separators/suffixes when reading
19017
input.  This should be used for yes/no answers, answers to
19018
end-of-game prompts, and so forth - for anything where we need to
19019
read input interactively in the course of a command.
19020
19021
</div>
19022
19023
<!------------------->
19024
<div class=entry>
19025
19026
Move en_us.t Thing vocabulary initialization code to VocabObject.
19027
19028
</div>
19029
19030
<!------------------->
19031
<div class=entry>
19032
19033
For commands like "put coin with jar," we're asking "what do you want
19034
to put," which is a weird question.  (This happens because we
19035
interpret this as "put coin with jar in missing-np" and then resolve
19036
the iobj first; this asks the usual question, which comes out the way
19037
it does because the dobj tentatively resolves to an empty list since
19038
it is a non-matching phrase.  To solve this, we could use a dummy
19039
entry in the tentative resolution list, to signal that we actually
19040
have a dobj phrase, even if it's not resolvable to anything.)
19041
19042
</div>
19043
19044
<!------------------->
19045
<div class=entry>
19046
19047
It might be nice to catch constructs like this:
19048
19049
<p><pre>
19050
>open door with key
19051
You see no door with key here.
19052
</pre>
19053
<p>
19054
In particular, it might be nice to recognize "&lt;nounPhrase> &lt;prep>
19055
&lt;nounPhrase>" constructs specifically, and flag them as "command not
19056
understood" errors instead of "object not seen" errors.  This could be
19057
handled by adding a "badness" production for np-prep-np structures for
19058
the prepositions commonly used in command phrases; by making this a
19059
badness match, we'll match it as a last resort when we can't find a
19060
valid verb phrase structure.
19061
19062
</div>
19063
19064
<!------------------->
19065
<div class=entry>
19066
19067
Add an extra category of reports, "extraReport", that's used to add
19068
extra information that doesn't replace any default report.  Use this
19069
for the key-found-on-keyring report, since this report is supplemental
19070
to any default Locked/Unlocked report and shouldn't suppress it.
19071
19072
</div>
19073
19074
<!------------------->
19075
<div class=entry>
19076
19077
Move the call to initializeVocab out of Thing.initializeThing, and
19078
instead call initializeVocab directly from adv3LibPreinit.execute()
19079
for each VocabObject.  (This will initialize vocabulary for non-Thing
19080
VocabObjects, such as Topic objects.)
19081
19082
</div>
19083
19084
<!------------------->
19085
<div class=entry>
19086
19087
Add a new inputManager method, promptForMore(), that shows the MORE
19088
prompt, taking care of flushing the transcript and dealing with the
19089
real-time clock.  The method should take an argument specifying
19090
whether or not to freeze the real-time clock; but even if the clock
19091
keeps running, real-time events shouldn't be allowed to occur until
19092
after the user acknowledges the MORE prompt, because otherwise we'd
19093
defeat the purpose of the MORE pause, which is to wait for user
19094
acknowledgment before showing any new output.
19095
19096
</div>
19097
19098
<!------------------->
19099
<div class=entry>
19100
19101
Change the Decoration class so that its generic not-important message
19102
can be overridden simply by changing a property, rather than having
19103
to override all of the Default handlers individually.
19104
19105
<p>
19106
Likewise for Distant and Intangible.
19107
19108
</div>
19109
19110
<!------------------->
19111
<div class=entry>
19112
19113
Add a new 'isTopLevel' property, which determines if an object is a
19114
top-level container within the game world.  Set this to nil by
19115
default for everything except Room objects, where we set it to true.
19116
Use this property in evaluating isIn(nil): for an object with a nil
19117
location, isIn(nil) returns true if and only if the object is NOT
19118
top-level.  This allows isIn(nil) to be used to sense whether or
19119
not the object is part of the game world, recursively considering
19120
the status of the object's containers.
19121
19122
</div>
19123
19124
<!------------------->
19125
<div class=entry>
19126
19127
Remove selfInReach from OutOfReach.
19128
19129
</div>
19130
19131
<!------------------->
19132
<div class=entry>
19133
19134
Fix problem with TravelConnector.verifyTravel(): when this routine is
19135
called, gVerifyResults is not reliably set to a valid list.  In
19136
particular, gVerifyResults must be set to a valid result list from
19137
TravelAction.verifyAction().
19138
19139
</div>
19140
19141
<!------------------->
19142
<div class=entry>
19143
19144
Turn on the sense cache while generating the status line.  Displaying
19145
the status line can involve some substantial sense calculations, so
19146
enabling caching while generating it can improve overall response
19147
time noticeably.
19148
19149
</div>
19150
19151
<!------------------->
19152
<div class=entry>
19153
19154
Fix 'follow wall' (generates nil pointer error)
19155
19156
</div>
19157
19158
<!------------------->
19159
<div class=entry>
19160
19161
Fix 'throw x at wall' (or floor or other room parts - nil pointer error)
19162
19163
</div>
19164
19165
<!------------------->
19166
<div class=entry>
19167
19168
Fix nil pointer error when addressing an ambiguous target actor.
19169
19170
</div>
19171
19172
<!------------------->
19173
<div class=entry>
19174
19175
<pre>
19176
>sit on darker chair
19177
>sit on chair
19178
Which one?
19179
>darker
19180
</pre>
19181
<p>
19182
This is allowed, but shouldn't be - the reply should be "you're
19183
already sitting on the darker chair."  (The problem is that we verify
19184
the lighter chair as okay, and we remember that we verified something
19185
as okay but don't bother remembering what; we need to track which
19186
objects we verify as okay individually.)
19187
19188
</div>
19189
19190
<!------------------->
19191
<div class=entry>
19192
19193
Make searching a surface (or looking in a surface) show the surface's
19194
contents.
19195
19196
</div>
19197
19198
<!------------------->
19199
<div class=entry>
19200
19201
Check bulk when adding a new item to a surface.  (This will fix the
19202
weird inconsistency with chairs that allows you to put an object
19203
on a chair you're sitting on, even if there's not room for you to
19204
sit on the chair when the object is already on it.)
19205
19206
</div>
19207
19208
<!------------------->
19209
<div class=entry>
19210
19211
Reduce the verification logical rank of non-Food objects for >TASTE.
19212
19213
</div>
19214
19215
<!------------------->
19216
<div class=entry>
19217
19218
<pre>
19219
>sit on chair
19220
>look
19221
... You contain a keyring ...
19222
</pre>
19223
<p>
19224
(We shouldn't mention your contents in that manner.  The problem is
19225
that Actor inherits contentsListed from Fixed; Actor should override
19226
contentsListed and set it to nil, since an actor's contents shouldn't
19227
be listed in the ordinary fashion in a room description.)
19228
19229
</div>
19230
19231
<!------------------->
19232
<div class=entry>
19233
19234
Show object contents for EXAMINE and LOOK IN to full depth.
19235
19236
</div>
19237
19238
<!------------------->
19239
<div class=entry>
19240
19241
Searching (or looking in) a room part shows contents as being "in"
19242
it, which isn't appropriate for walls, ceilings, or floors.
19243
19244
</div>
19245
19246
<!------------------->
19247
<div class=entry>
19248
19249
For THROW AT FLOOR, perhaps we should have a message other than
19250
"Dropped" - something indicating the action is more violent than
19251
just setting the object down.
19252
19253
</div>
19254
19255
<!------------------->
19256
<div class=entry>
19257
19258
Make contents listings go to arbitrary depth.  Rather than showing a
19259
separate list for the contents of top-level list items, show the
19260
contents of each item parenthetically, and then recursively add these
19261
parenthetical lists to show all contents.  (Only do this when the
19262
ListRecurse flag is set.)
19263
19264
<p>
19265
Add a new Thing property, contentsListedSeparately, that allows an
19266
object to control whether its contents are listed in the new in-line
19267
style, or as the traditional separate list.  Make this nil by default.
19268
19269
</div>
19270
19271
<!------------------->
19272
<div class=entry>
19273
19274
For "tall" listings, show contents of unlisted top-level items in
19275
separate lists after the main list, just as we do for "wide" listings.
19276
19277
</div>
19278
19279
<!------------------->
19280
<div class=entry>
19281
19282
Remove the need to call showContentsList() separately after showList();
19283
instead, call this automatically from showList() if the ListRecurse
19284
flag is set.
19285
19286
</div>
19287
19288
<!------------------->
19289
<div class=entry>
19290
19291
Throwing destinations aren't working quite right.  Refactor things a
19292
bit: rename getFallDestination() to getHitFallDestination(), and give
19293
it the previous container in the path as a parameter, so that it can
19294
decide whether the object is being thrown from inside or outside (or,
19295
in the case of a multi-location item, the source location).  Make
19296
things drop to the floor in most cases; games can override to make
19297
things fall into intermediate containers when desired.
19298
19299
</div>
19300
19301
<!------------------->
19302
<div class=entry>
19303
19304
Change Actor.standUp to use reportFailure() when already standing.
19305
19306
</div>
19307
19308
<!------------------->
19309
<div class=entry>
19310
<p><pre>
19311
>out
19312
Out of what?
19313
>e
19314
You can't get out of that (the east wall).
19315
</pre>
19316
<p>
19317
It would be nice to treat such responses as new commands.  We could
19318
probably adopt the heuristic that we give the new command
19319
interpretation priority over the noun phrase interpretation of a reply
19320
to this prompt.  Anything that looks like both a syntactically valid
19321
noun phrase and a syntactically valid command probably matches the
19322
noun phrase syntax only because it's extremely abbreviated; the
19323
chances of the verb phrase match being an accident are somewhat less.
19324
In addition, it should be less confusing to the user to treat the
19325
response as a new command when a noun phrase was intended than vice
19326
versa, and it should be fairly obvious how to force a noun phrase
19327
interpretation (adding "the" would do the trick, for example).
19328
19329
</div>
19330
19331
<!------------------->
19332
<div class=entry>
19333
19334
Can we go to arbitrary depth for contentsListedSeparately?  In particular:
19335
19336
<p><pre>
19337
  >i
19338
  You are carrying a duffel bag (which contains a pen cup).  The 
19339
  pen cup contains four pens.
19340
</pre>
19341
<p>
19342
Right now, we're not adding that bit about the pens, because we think
19343
we're done with the top-level list, as we've already listed
19344
everything: we scan the duffel, and decide that we don't need to
19345
recurse into it, since it's listed and has in-line listed contents.
19346
What we'd need to do is add another recursive descent to look for
19347
everything that we listed at the second (or deeper) level that has
19348
contentsListedSeparately.
19349
19350
</div>
19351
19352
<!------------------->
19353
<div class=entry>
19354
19355
Tweak the parser's command match-tree ranking mechanism a little, so
19356
that differences in the number of occurrences of a problem are counted
19357
in a second pass, after we've exhausted the possibility of any
19358
differences in the presence or absence of problems.  This will make
19359
slightly better choices in certain cases, such as when we have two
19360
separate noun phrases in the action, and one interpretation treats
19361
only one as ending in an adjective while the other has an adjective
19362
ending in both phrases.
19363
19364
</div>
19365
19366
<!------------------->
19367
<div class=entry>
19368
19369
Add a profiling facility, to gather statistics for performance
19370
optimizations in the library.
19371
19372
</div>
19373
19374
<!------------------->
19375
<div class=entry>
19376
19377
Rename senseInfoList to senseInfoTable, and make it return a
19378
LookupTable rather than a list.  Sense information lists are almost
19379
always used as random-access tables, so we can speed up some
19380
operations by representing these as lookup tables keyed on object.
19381
19382
</div>
19383
19384
<!------------------->
19385
<div class=entry>
19386
19387
Rename connectionList to connectionTable, and make it return a
19388
LookupTable rather than a list.  Since we want only one copy of each
19389
object in the result, it's faster to build this as a lookup table,
19390
where we can determine whether or not an object is already present
19391
much more quickly than we can with a vector.
19392
19393
</div>
19394
19395
<!------------------->
19396
<div class=entry>
19397
19398
<pre>
19399
>e
19400
>put cup in desk
19401
>undo
19402
</pre>
19403
<p>
19404
(Takes back turns through "e".  The problem is that we're marking a
19405
remapped action as a nested action; it's not really nested, because
19406
the original action is completely replaced and will never reach the
19407
execution phase.  Do not mark remapped actions as nested.)
19408
19409
</div>
19410
19411
<!------------------->
19412
<div class=entry>
19413
19414
Add Thing.specialDescOrder to control specialDesc the relative order
19415
of specialDesc listings.
19416
19417
</div>
19418
19419
<!------------------->
19420
<div class=entry>
19421
19422
Change the format of the first-score-notification supplemental
19423
message, which explains how to turn off score notifications: rather
19424
than showing it as part of the same paragraph with the score, start a
19425
new line and show it as a separate notification message.
19426
19427
</div>
19428
19429
<!------------------->
19430
<div class=entry>
19431
19432
Rename UnqualifiedPluralProd to DefinitePluralProd.  In the English
19433
parser, base implicitDetPluralOnlyNounPhrase(main) and
19434
explicitDetPluralNounPhrase(definite) on DefinitePluralProd, since
19435
"books" and "the books" should act the same way in English.
19436
19437
</div>
19438
19439
<!------------------->
19440
<div class=entry>
19441
19442
Simplify the Key and Keyring Attach and Detach handling by using
19443
remapTo() in the keyring: remap "attach x to keyring" to "put x on
19444
keyring" in Keyring.iobjFor(AttachTo), and remap "detach x from
19445
keyring" to "take x from keyring" in Keyring.iobjFor(DetachFrom).
19446
This removes a bunch of code from Key to handle the remapping at its
19447
end - that code all predated the remap mechanism, and can now be
19448
greatly simplified by using the new mechanism.
19449
19450
</div>
19451
19452
<!------------------->
19453
<div class=entry>
19454
19455
Fix a problem in vocabulary initialization: if a hyphen is used as a
19456
placeholder in a vocabWords_ setting, the hyphen is added to the
19457
object's part-of-speech property (it's not added to the dictionary,
19458
but it does show up in the list for the part-of-speech property).  It
19459
should be omitted from the list, since it's not really a vocabulary
19460
word.
19461
19462
</div>
19463
19464
<!------------------->
19465
<div class=entry>
19466
19467
Fix finishOptionUndo so that it can be used in daemons.  This requires
19468
a couple of changes.  First, remove the transcript flush - this is a
19469
relic of the pre-'transient' transcript mechanism and is no longer
19470
needed.  Second, daemons and fuses need to be able to use
19471
TerminateCommandException and the like to exit, so we should catch
19472
command-ending exceptions in the event manager.
19473
19474
</div>
19475
19476
<!------------------->
19477
<div class=entry>
19478
19479
Fix examining sightSize=large objects at a distance.  (The problem is
19480
that Thing.canDetailsBeSensed() is attenuating the ambient light level
19481
for the sense path, which is unnecessary as the SenseInfo already does
19482
this.  canDetailsBeSensed doesn't need to go to so much trouble - any
19483
SenseInfo with trans != opaque indicates the object can be sensed,
19484
since trans will always be set to opaque for objects that cannot be
19485
sensed.)
19486
19487
</div>
19488
19489
<!------------------->
19490
<div class=entry>
19491
19492
Add tok.t to system.tl.  (This file isn't actually necessary to
19493
compile a simple program, which is why it hasn't been in system.tl all
19494
along; but it is necessary for any game based on the library, so on
19495
balance it's probably better to include it in the default library.
19496
19497
</div>
19498
19499
<!------------------->
19500
<div class=entry>
19501
19502
Separate some action-time checks into check() routines:
19503
Container.dobjFor(LookIn); Dial.dobjFor(TurnTo) (this could perhaps
19504
benefit from some 'verify' checking of the literal value as well).
19505
19506
</div>
19507
19508
<!------------------->
19509
<div class=entry>
19510
19511
Add a specialDescLister, and use it for listing special descriptions.
19512
Add a new property of Thing, specialDescListWith, which returns a list
19513
group to use when showing special descriptions; use this new list
19514
group generator in specialDescLister.  This will allow special
19515
descriptions to be grouped when desired, simply by using the standard
19516
list grouping mechanism.
19517
19518
</div>
19519
19520
<!------------------->
19521
<div class=entry>
19522
19523
Add an "isCircularPassage" property to TravelConnector: when this
19524
property of the connector is true, fully describe travel that winds
19525
up in the origin.  (We normally don't bother describing such circular
19526
trips, but sometimes it's desirable to be able to do so.)
19527
19528
</div>
19529
19530
<!------------------->
19531
<div class=entry>
19532
19533
In en_us.t, add askDobjResponseProd=singleNoun for each action that
19534
takes a singleDobj as its direct object.
19535
19536
</div>
19537
19538
<!------------------->
19539
<div class=entry>
19540
19541
In en_us.t, remove the redundant syntax for "walk in/into" and "go
19542
in/into" from VerbRule(GoThrough), as these are already handled by
19543
VerbRule(Enter).
19544
19545
</div>
19546
19547
<!------------------->
19548
<div class=entry>
19549
19550
In en_us.t, use <Q> tags wherever literal quotes are used, rather than
19551
ASCII-34 quotes.
19552
19553
</div>
19554
19555
<!------------------->
19556
<div class=entry>
19557
19558
Convert the parser to use the new Dictionary API.  In the English
19559
parser, install a StringComparator to perform case folding and
19560
truncation matching.  Remove case conversions from the English
19561
tokenizer, as they're not needed with the StringComparator.
19562
19563
</div>
19564
19565
<!------------------->
19566
<div class=entry>
19567
19568
Refactor the travel connector operations so that everything turns into
19569
a TravelVia on its connector.  Handle direction commands ("go north")
19570
by using replaceAction(TravelVia, connector).  This simplifies the
19571
travel verbs, and makes the task of defining travel connectors more
19572
consistent with defining other action handlers.
19573
19574
</div>
19575
19576
<!------------------->
19577
<div class=entry>
19578
19579
Move the travel connector checks for dark-to-dark travel and for
19580
travel barriers into the TravelVia check() handler.
19581
19582
</div>
19583
19584
<!------------------->
19585
<div class=entry>
19586
19587
Rearrange the room description code (lookAroundPov, etc) so that
19588
lookAround can be called on any object.  To do this, move all of the
19589
room description mechanism from BasicLocation into Thing, and work the
19590
NestedRoom code into the Thing code for descriptions.
19591
19592
</div>
19593
19594
<!------------------->
19595
<div class=entry>
19596
19597
Add a return value to basicEventManager.removeMatchingEvents,
19598
indicating whether or not a matching event was actually found.
19599
19600
</div>
19601
19602
<!------------------->
19603
<div class=entry>
19604
19605
Fix getTenativeLiteralText argument mismatches in parser.t when
19606
calling getLiteralText.
19607
19608
</div>
19609
19610
<!------------------->
19611
<div class=entry>
19612
19613
In MessageBuilder.generateMessage(), for the case where we're
19614
substituting '{actor}' but there's no current action, use the current
19615
gActor value if it's not nil, or gPlayerChar if gActor is nil (rather
19616
than always using gPlayerChar - using gActor instead allows a daemon
19617
or other non-action message producer to set gActor to indicate the
19618
actor doing whatever it is that's generating the message).
19619
19620
</div>
19621
19622
<!------------------->
19623
<div class=entry>
19624
19625
In Actor.addPendingAction() and addFirstPendingAction(), take
19626
a resolved object list as the last varargs-list argument, and pass
19627
it to the PendingCommandInfo constructor.
19628
19629
</div>
19630
19631
<!------------------->
19632
<div class=entry>
19633
19634
Hide Fixed objects from "drop all".
19635
19636
</div>
19637
19638
<!------------------->
19639
<div class=entry>
19640
19641
Add some more default verbs: CutWith, Kiss.
19642
19643
</div>
19644
19645
<!------------------->
19646
<div class=entry>
19647
19648
Add RoomPart.isIn().  Consider a RoomPart to be within a given location
19649
if its room part location is equal to or within the given location, or
19650
the inherited isIn returns true.
19651
19652
</div>
19653
19654
<!------------------->
19655
<div class=entry>
19656
19657
Add some more string-quoting styles to the English tokenizer: `like
19658
this', and with typographical ("curly") single and double quotes
19659
(\u2018 and \u2019 for single quotes, \u201c and \u201d for double).
19660
19661
</div>
19662
19663
<!------------------->
19664
<div class=entry>
19665
19666
Add a quotedStringPhrase production type, for rules that explicitly
19667
call for quoted strings (but not unquoted literal text).  Use this
19668
production to build the quoted string rule for literalPhrase.
19669
19670
</div>
19671
19672
<!------------------->
19673
<div class=entry>
19674
19675
Add SAVE, RESTORE, and SCRIPT command variations that take quoted
19676
strings giving the filenames to use.
19677
19678
</div>
19679
19680
<!------------------->
19681
<div class=entry>
19682
19683
Traveler.travelTo in a daemon dereferences gAction - check to see if
19684
gAction is nil, and skip that step if so.
19685
19686
</div>
19687
19688
<!------------------->
19689
<div class=entry>
19690
19691
Change all uses of 'seen' to use the seenBy() and setSeenBy() methods.
19692
Move these from BasicLocation into Thing so that all objects uses them
19693
uniformly.
19694
19695
</div>
19696
19697
<!------------------->
19698
<div class=entry>
19699
19700
Bug: TERSE mode doesn't show full descriptions on first entry.
19701
19702
</div>
19703
19704
<!------------------->
19705
<div class=entry>
19706
19707
Some of the objects shown in the introductory room description aren't
19708
getting marked as seen.  (The problem is that Thing.lookAroundWithin
19709
is using gActor in a few places where it should be using the 'actor'
19710
parameter.)
19711
19712
</div>
19713
19714
<!------------------->
19715
<div class=entry>
19716
19717
Bug: NoTravelMessage is commented as being an apparent connector, but
19718
is implemented as a non-apparent connector.  Leave the implementation
19719
the way it is, but fix the comments, and add a new class that acts the
19720
same as NoTravelMessage but has an apparent connector (call it
19721
FakeConnector, perhaps).
19722
19723
</div>
19724
19725
<!------------------->
19726
<div class=entry>
19727
19728
Rename LiteralAction to LiteralTAction.  Add a new LiteralAction
19729
class that takes only a literal phrase as its object (i.e., no other
19730
direct object), for commands like "say random stuff".
19731
19732
Note that DefineLiteralAction is likewise renamed to
19733
DefineLiteralTAction, and we add a new DefineLiteralAction for
19734
defining an action with only a literal phrase for its object.
19735
19736
</div>
19737
19738
<!------------------->
19739
<div class=entry>
19740
19741
Add a PostUndoObject class, analogous to PostRestoreObject.
19742
19743
</div>
19744
19745
<!------------------->
19746
<div class=entry>
19747
19748
Reduce parse rankings for pronoun phrases vs noun phrases: if a word
19749
is explicitly defined as noun, it probably should be a stronger match
19750
than a pronoun interpretation of the same word.
19751
19752
</div>
19753
19754
<!----------------------------------- 3.0.4 --------------------------------->
19755
<div class=sepbar><a name='304'></a>3.0.4 and earlier</div>
19756
19757
<div class=firstentry>
19758
19759
Consider this command:
19760
19761
<p><pre>
19762
>put ball in asdf
19763
Which ball do you mean, the red ball, or the green ball?
19764
19765
>red
19766
The story doesn't know the word 'asdf'.
19767
19768
>oops box
19769
Which ball do you mean, the red ball, or the green ball?
19770
</pre>
19771
19772
<p>
19773
The issue is that OOPS retries the entire command with an updated
19774
token list, and as a result, the disambiguation work from the first
19775
attempt at resolving the objects is lost for the second iteration.
19776
The reparsing is necessary, since the corrected typo could change
19777
the entire meaning of the command.
19778
19779
<p>
19780
One possible solution: add a resolution pass specifically to catch
19781
unknown words.  Don't do any other resolution on this pass - just
19782
deal with unknown words.  This would ensure that we process OOPS
19783
before we ask any disambiguation questions.
19784
19785
<p>
19786
Another possibility: keep a set of answers to questions, and the
19787
conditions under which the questions were asked.  Clear the list
19788
each time we start a new parsing from scratch, but let the list
19789
survive if we reparse a token list.  Whenever we're about to ask
19790
a question, look to see if the same question has been asked with
19791
the same conditions, and if so, reuse the same response.
19792
19793
</div>
19794
19795
<!------------------->
19796
<div class=entry>
19797
19798
All
19799
19800
</div>
19801
19802
<!------------------->
19803
<div class=entry>
19804
19805
Missing noun phrases: prompt for input when PC gave command
19806
19807
</div>
19808
19809
<!------------------->
19810
<div class=entry>
19811
19812
Missing noun phrases: use a default when possible
19813
19814
</div>
19815
19816
<!------------------->
19817
<div class=entry>
19818
19819
Object announcements: include a preposition when appropriate (announcing
19820
indirect object, announcing direct object with verb taking a preposition:
19821
">dig \n (in the dirt)")
19822
19823
</div>
19824
19825
<!------------------->
19826
<div class=entry>
19827
19828
Pronouns
19829
19830
</div>
19831
19832
<!------------------->
19833
<div class=entry>
19834
19835
Again
19836
19837
</div>
19838
19839
<!------------------->
19840
<div class=entry>
19841
19842
Again: should we use disambiguation information from past commands?
19843
For example:
19844
19845
<p><pr>
19846
>take book
19847
Which book do you mean, the red one, the blue one, or the green one?
19848
19849
>blue
19850
Taken.
19851
19852
>g
19853
</pre>
19854
19855
<p>
19856
Should this 'take blue book' or should it ask...
19857
Which book do you mean, the blue one, or the green one?
19858
19859
<p>
19860
Right now we use the literal tokens from the original command, so we
19861
ask the disambiguation question again.  This is exactly what we want
19862
in cases with indistinguishables:
19863
19864
<p>
19865
<pre>
19866
You see five silver coins here.
19867
>take coin
19868
Taken.
19869
>g
19870
Taken.
19871
</pre>
19872
19873
<p>
19874
But in cases where we have distinguishable objects, we probably want
19875
the resolved objects, not the words.
19876
19877
<p>
19878
We probably want to distinguish this way: if we had indefinites or
19879
indistinguishables, resolve again from the original text.  Otherwise,
19880
use the original resolution.
19881
19882
</div>
19883
19884
<!------------------->
19885
<div class=entry>
19886
19887
disambiguation: we're not keeping the full list properly in cases of
19888
indistinguishables:
19889
19890
<p>
19891
<pre>
19892
>take coin
19893
Which coin, a gold coin, or a silver coin?
19894
19895
>coin
19896
Which coin, the silver coin, or the gold coin?
19897
</pre>
19898
19899
<p>
19900
The second time around, the cardinality of the full list should not change,
19901
so we should be asking the same question as the first time.
19902
19903
</div>
19904
19905
<!------------------->
19906
<div class=entry>
19907
19908
Preconditions
19909
19910
</div>
19911
19912
<!------------------->
19913
<div class=entry>
19914
19915
We need 'touchDobj' and 'touchIobj' preconditions - use these for all
19916
objects that require that the object be physically manipulated by the
19917
actor but not necessarily held.  These are required to deal with things
19918
like the contents of a closed transparent container, where an object
19919
can be in scope but cannot be manipulated.
19920
19921
<p>
19922
As part of this, we need to find a way to say what object blocks a
19923
sense path opaquely, so that we can say why we can't touch something
19924
that we can see.  There are two main cases: containers are in the way,
19925
and connectors are in the way.
19926
19927
</div>
19928
19929
<!------------------->
19930
<div class=entry>
19931
19932
Bag of holding: when an actor's hands are full and the actor is trying
19933
to take something, pick a held object and try to find a bag of holding
19934
for it.  First, check the object's preferredHolder property - this
19935
gives an object or class that the object prefers as its bag of holding.
19936
If the actor is holding such a holder, move the object to the holder.
19937
If we can't find any affinity, look for any object the actor is holding
19938
of the generic BagOfHolding class.
19939
19940
<p>
19941
Examples of specialized bags of holding: wallet, key ring, purse, duffel
19942
bag.
19943
19944
</div>
19945
19946
<!------------------->
19947
<div class=entry>
19948
19949
Formatting: where does the blank line come from before an implicit
19950
message for a single command?
19951
19952
</div>
19953
19954
<!------------------->
19955
<div class=entry>
19956
19957
use disambiguation filter even for indefinites, so we pick the best
19958
possibility if there are objects of different likelihoods
19959
19960
</div>
19961
19962
<!------------------->
19963
<div class=entry>
19964
19965
"The red one" should work for exclusion lists.  It should probably also
19966
work in general - although 'one' should bind more tightly to an actual
19967
name, in the absence of a name it should serve as a generic noun.
19968
19969
</div>
19970
19971
<!------------------->
19972
<div class=entry>
19973
19974
"drop coins" - should we consider only the ones we're carrying?  In other
19975
words, should we run verification and include only the logical ones?
19976
Probably - if there are some logical and some not logical, apply the
19977
command only to the logical ones; otherwise, apply the command to all
19978
of them.
19979
19980
</div>
19981
19982
<!------------------->
19983
<div class=entry>
19984
19985
"take both coins" - really wacky
19986
19987
</div>
19988
19989
<!------------------->
19990
<div class=entry>
19991
19992
"take two gold" should work (i.e., quantified ending in adjective)
19993
19994
</div>
19995
19996
<!------------------->
19997
<div class=entry>
19998
19999
consider:
20000
20001
<p>
20002
<pre>
20003
>take both coins
20004
Which two (of five gold coins or three silver coins) do you mean?
20005
20006
>two gold
20007
You don't see that many coins here.
20008
</pre>
20009
20010
<p>
20011
The problem is that we disambiguate with the reduced match list.
20012
20013
</div>
20014
20015
<!------------------->
20016
<div class=entry>
20017
20018
<pre>
20019
>take coin
20020
Which coin, gold, silver, or copper?
20021
20022
>all but copper
20023
</pre>
20024
20025
<p>
20026
no worky - might even be a gram prod bug, since we seem to have a weird
20027
firstToken/lastToken value in these cases
20028
20029
</div>
20030
20031
<!------------------->
20032
<div class=entry>
20033
20034
"take books except red" - disambiguation of the exclusion list should be
20035
limited in scope to the resolved plural list.
20036
20037
</div>
20038
20039
<!------------------->
20040
<div class=entry>
20041
20042
"take books except silver" - "You see no silver here" - this should
20043
ignore the missing object.
20044
20045
</div>
20046
20047
<!------------------->
20048
<div class=entry>
20049
20050
"take coins except copper" - the 'copper' should implicitly be plural
20051
rather than indefinite so that we skip all of the copper coins if there
20052
are several
20053
20054
</div>
20055
20056
<!------------------->
20057
<div class=entry>
20058
20059
<pre>
20060
>take gold coin, gold coin
20061
gold coin: Taken.
20062
gold coin: You're already carrying the gold coin.
20063
</pre>
20064
20065
<p>
20066
When we have multiple equivalent items in scope, and we mention several
20067
items in a list, we should pick separate equivalent instances for each
20068
mention.
20069
20070
<p>
20071
This should apply to disambiguation responses, too:
20072
20073
<p>
20074
<pre>
20075
>take coin
20076
Which coin do you mean, a gold coin or a silver coin?
20077
20078
>gold, gold
20079
</pre>
20080
20081
</div>
20082
20083
<!------------------->
20084
<div class=entry>
20085
20086
"take any ball except green" - takes the green if there's nothing else
20087
left
20088
20089
</div>
20090
20091
<!------------------->
20092
<div class=entry>
20093
20094
add verification for pre-conditions - objHeld, for example, would boost
20095
the likelihood for a held object
20096
20097
</div>
20098
20099
<!------------------->
20100
<div class=entry>
20101
20102
add the new pre-execution check as a separate phase (checkXxx?)
20103
20104
</div>
20105
20106
<!------------------->
20107
<div class=entry>
20108
20109
output capturers - one at a time
20110
20111
</div>
20112
20113
<!------------------->
20114
<div class=entry>
20115
20116
add object affinities for bag of holding
20117
20118
</div>
20119
20120
<!------------------->
20121
<div class=entry>
20122
20123
key ring - not just a bag of holding, but automatically adds items
20124
as they're picked up when the key ring is in inventory
20125
20126
</div>
20127
20128
<!------------------->
20129
<div class=entry>
20130
20131
Key ring messages: we should check for a non-default report, and if there
20132
is no non-default report we should include more details: "You take the
20133
key and put it on the keyring."
20134
20135
</div>
20136
20137
<!------------------->
20138
<div class=entry>
20139
20140
Probably should have an objDirectlyHeld precondition.  This one would
20141
be used for commands that physically move an object; objHeld would
20142
continue to be used for commands that merely need to do something
20143
with an object.  So, "put x in y" would require that x is directly
20144
held, while "unlock x with y" would only require that y be nominally
20145
held.  For objDirectlyHeld, we'll make the implicit command silent
20146
if the object is being indirectly carried, so that we don't get weird
20147
things like this:
20148
20149
<p>
20150
<pre>
20151
>i
20152
You are carrying a paper bag.  The paper bag contains a key.
20153
20154
>drop key
20155
(First taking the key)
20156
Dropped.
20157
</pre>
20158
20159
</div>
20160
20161
<!------------------->
20162
<div class=entry>
20163
20164
If there's no doXxx, fail verification with a generic Illogical('you
20165
can\'t do that').
20166
20167
</div>
20168
20169
<!------------------->
20170
<div class=entry>
20171
20172
For travel: shouldn't we have a verify phase for moving the actor?
20173
20174
</div>
20175
20176
<!------------------->
20177
<div class=entry>
20178
20179
need to export propNotDefined in a system file
20180
20181
</div>
20182
20183
<!------------------->
20184
<div class=entry>
20185
20186
take key: if it started on the keyring, we should take it off the
20187
keyring
20188
20189
</div>
20190
20191
<!------------------->
20192
<div class=entry>
20193
20194
Travel connectors
20195
20196
</div>
20197
20198
<!------------------->
20199
<div class=entry>
20200
20201
Fix 'i tall' listings to show contents with a better format
20202
20203
</div>
20204
20205
<!------------------->
20206
<div class=entry>
20207
20208
Move senses to a separate module.
20209
20210
</div>
20211
20212
<!------------------->
20213
<div class=entry>
20214
20215
<pre>
20216
>get coin
20217
Which coin, a gold coin, a copper coin, or a silver coin?
20218
20219
>coin
20220
Which coin, a copper coin, a silver coin, or a gold coin?
20221
</pre>
20222
20223
<p>
20224
The re-ordering on the second round is weird - we should keep the order
20225
stable if we can.
20226
20227
</div>
20228
20229
<!------------------->
20230
<div class=entry>
20231
20232
<pre>
20233
>get ball
20234
Which ball, red or green?
20235
20236
>blue
20237
You don't see that here.
20238
</pre>
20239
20240
<p>
20241
The error shouldn't be "you don't see that here" - it should be more
20242
like "that's not one of the choices you were offered."  However, it
20243
would be better to widen the scope again to the real scope, rather
20244
than failing.
20245
20246
</div>
20247
20248
<!------------------->
20249
<div class=entry>
20250
20251
Add maxWeight and weight enforcement
20252
20253
</div>
20254
20255
<!------------------->
20256
<div class=entry>
20257
20258
Move pre-conditions to the objects.  Keep the verb preconditions as
20259
well, but verb-specific pre-conditions should never mention the
20260
objects.
20261
20262
</div>
20263
20264
<!------------------->
20265
<div class=entry>
20266
20267
Mark objects for which we've displayed descriptions, for topic scoping
20268
20269
</div>
20270
20271
<!------------------->
20272
<div class=entry>
20273
20274
Add "module ID" objects, for library extensions.  The "credits" command
20275
should run through the module ID's and show a credit for each one.
20276
20277
</div>
20278
20279
<!------------------->
20280
<div class=entry>
20281
20282
Make styles into objects
20283
20284
</div>
20285
20286
<!------------------->
20287
<div class=entry>
20288
20289
Fuses and daemons
20290
20291
</div>
20292
20293
<!------------------->
20294
<div class=entry>
20295
20296
Need to apply logical tests again after running preconditions.  (Try
20297
this: "put rusty key on keyring" - it'll pick up the key for the
20298
'held' precondition, which will put the key on the keyring, but then
20299
the explicit put-on-keyring command will succeed, which it shouldn't.)
20300
20301
</div>
20302
20303
<!------------------->
20304
<div class=entry>
20305
20306
Generalize the showList mechanism to allow for other types of
20307
hierarchies besides contents to be shown.  Use the lister interface
20308
to virtualize the hierarchy traversal.
20309
20310
</div>
20311
20312
<!------------------->
20313
<div class=entry>
20314
20315
Use the generic showList mechanism for the full score lister, rather
20316
than using a specialized lister that does essentially the same thing.
20317
20318
</div>
20319
20320
<!------------------->
20321
<div class=entry>
20322
20323
Score change notifications: add daemon that senses score changes and
20324
notifies between turns.
20325
20326
</div>
20327
20328
<!------------------->
20329
<div class=entry>
20330
20331
Do not count the time taken for implicit commands.
20332
20333
</div>
20334
20335
<!------------------->
20336
<div class=entry>
20337
20338
Add a "message generation context" that determines what is generating
20339
messages.  This object must be sensible to the player character for
20340
messages to be generated.  For convenience, define a callWithMessageContext
20341
function that establishes the context, invokes a callback, then restores
20342
the enclosing context.
20343
20344
<p>
20345
When establishing a new context, we check to see if the generator is in
20346
scope in the given sense.  If not, we hide messages; if so, we show
20347
messages.
20348
20349
<p>
20350
A nested context should actually be considered a context switch,
20351
because we don't want an enclosing hiding context to hide an enclosed
20352
showing context.  For example, if we are generating messages with
20353
sight scope for Lloyd, and we have a nested context where Lloyd is
20354
saying something and so we now are in hearing scope for Lloyd, we
20355
want the nested context to show its messages if in fact Lloyd is in
20356
hearing scope even if Lloyd is not in sight scope (maybe the player
20357
character and Lloyd are in contact over a walkie-talkie).
20358
20359
</div>
20360
20361
<!------------------->
20362
<div class=entry>
20363
20364
NPC messages: only show if NPC is in sight of PC (using message generation
20365
context)
20366
20367
</div>
20368
20369
<!------------------->
20370
<div class=entry>
20371
20372
Use message generation context for fuses and daemons.  Allow events to
20373
be created with a context object and sense object; whenever an event
20374
is executed, establish the context for the duration of the event's
20375
execution.
20376
20377
</div>
20378
20379
<!------------------->
20380
<div class=entry>
20381
20382
try this: bob, n. z. s. / n. z
20383
20384
<p>
20385
We should see bob leaving on his third queued move, but we don't for
20386
some reason.
20387
20388
</div>
20389
20390
<!------------------->
20391
<div class=entry>
20392
20393
Do we really want to remove the objects directly involved in a command
20394
from the beforeAction and afterAction processing?  It seems like it's
20395
an unnecessary inconsistency.
20396
20397
</div>
20398
20399
<!------------------->
20400
<div class=entry>
20401
20402
Should consider directing report messages to the pc/npc message
20403
objects.  This would more readily allow separate messages for
20404
reporting the results of pc and npc commands (for example, "Taken" vs
20405
"Bob takes the book").  This is probably trivial, since we already
20406
have the pc/npc message generator division anyway; we probably just
20407
need to use it rather than verbMessages for generating report
20408
messages.  (If there's really a good reason to have a separate
20409
verbMessage object, maybe we should have a per-actor verbMessages
20410
object, the way we do with the default library messages generator.)
20411
20412
</div>
20413
20414
<!------------------->
20415
<div class=entry>
20416
20417
Missing blank line between commands on parser failures:
20418
20419
<p>
20420
<pre>
20421
>bob, n. get silver coin.
20422
>n
20423
</pre>
20424
20425
</div>
20426
20427
<!------------------->
20428
<div class=entry>
20429
20430
In room descriptions, list actors separately.
20431
20432
</div>
20433
20434
<!------------------->
20435
<div class=entry>
20436
20437
Don't let the room lister include actor inventory listings with the
20438
main room contents listing.
20439
20440
</div>
20441
20442
<!------------------->
20443
<div class=entry>
20444
20445
Footnote system
20446
20447
</div>
20448
20449
<!------------------->
20450
<div class=entry>
20451
20452
Add an initExamineDesc, to parallel initDesc when an object is
20453
in its initial position and is explicitly examined.
20454
20455
</div>
20456
20457
<!------------------->
20458
<div class=entry>
20459
20460
Check changes in object bulks for effects on containers.  If a
20461
container doesn't allow a change in child bulk, fail the command
20462
that attempted the change.  (For example, in a stretchy bag,
20463
putting a new object into the bag should be disallowed if doing
20464
so would make expand the bag so much that the bag would be too
20465
large for its own container.)
20466
20467
</div>
20468
20469
<!------------------->
20470
<div class=entry>
20471
20472
Stretchy bags, that conform to their contents (in the sense that
20473
the bulk changes according to its contents)
20474
20475
</div>
20476
20477
<!------------------->
20478
<div class=entry>
20479
20480
Use normal command result reports (especially ReportFailure) in
20481
precondition checks.
20482
20483
</div>
20484
20485
<!------------------->
20486
<div class=entry>
20487
20488
For target of "put in", elevate likelihood for an item being held.
20489
20490
</div>
20491
20492
<!------------------->
20493
<div class=entry>
20494
20495
implement save/restore
20496
20497
</div>
20498
20499
<!------------------->
20500
<div class=entry>
20501
20502
implement restart
20503
20504
</div>
20505
20506
<!------------------->
20507
<div class=entry>
20508
20509
implement undo
20510
20511
</div>
20512
20513
<!------------------->
20514
<div class=entry>
20515
20516
For undoing commands to NPC's, show the NPC as part of the command
20517
being undone: "undoing one command: bob, go north".
20518
20519
</div>
20520
20521
<!------------------->
20522
<div class=entry>
20523
20524
Add '\{' and '\}' (push/pop formatter state) output sequences.
20525
20526
</div>
20527
20528
<!------------------->
20529
<div class=entry>
20530
20531
Implicit commands should not set antecedents.
20532
20533
</div>
20534
20535
<!------------------->
20536
<div class=entry>
20537
20538
"Take All" should include the non-fixed contents of fixed containers
20539
and surfaces within the room.
20540
20541
</div>
20542
20543
<!------------------->
20544
<div class=entry>
20545
20546
Status line
20547
20548
</div>
20549
20550
<!------------------->
20551
<div class=entry>
20552
20553
Footnotes: add FOOTNOTE MEDIUM mode, which shows new footnote
20554
references but hides references to footnotes that have already
20555
been read.  This helps cut down on unnecessary clutter, since
20556
a footnote reference is unlikely to be of much interest once
20557
it's been read, assuming that footnotes are always extra
20558
information that isn't required to finish the game.
20559
20560
</div>
20561
20562
<!------------------->
20563
<div class=entry>
20564
20565
Weird:
20566
20567
<p>
20568
<pre>
20569
>get large red ball, small red ball and drop them
20570
[works]
20571
20572
>get asdf red ball, small red ball and drop them
20573
Don't know the word 'asdf'
20574
20575
>oops large
20576
...you see no drop them here
20577
</pre>
20578
20579
<p>
20580
Why does it pick out the right interpretation normally but can't
20581
on a token reparse?
20582
20583
</div>
20584
20585
<!------------------->
20586
<div class=entry>
20587
20588
Add an "unobvious" verification mode that allows the command but will
20589
not be accepted as a default.
20590
20591
</div>
20592
20593
<!------------------->
20594
<div class=entry>
20595
20596
Decorations
20597
20598
</div>
20599
20600
<!------------------->
20601
<div class=entry>
20602
20603
Add dobjCheck, iobjCheck, dobjGen, iobjGen equivalents
20604
20605
</div>
20606
20607
<!------------------->
20608
<div class=entry>
20609
20610
Add a default mechanism for listing the inventory of an actor as
20611
part of the actor's description.  ("Bob is carrying...wearing...").
20612
20613
</div>
20614
20615
<!------------------->
20616
<div class=entry>
20617
20618
Add a sorter method to the list group object, for simple control over
20619
the sorting order
20620
20621
</div>
20622
20623
<!------------------->
20624
<div class=entry>
20625
20626
Add input font switch when reading a command
20627
20628
</div>
20629
20630
<!------------------->
20631
<div class=entry>
20632
20633
When defaulting a direct object of a two-object command, include the
20634
verb's participle form in the default message:
20635
20636
<p>
20637
<pre>
20638
>ask about watch
20639
(asking Bob)
20640
</pre>
20641
20642
<p>
20643
Most default messages are meant to be tagged onto the end of the
20644
command line, but when we're adding a direct object to a two-object
20645
verb, the added object goes in the middle of the command and hence
20646
the default phrase doesn't sound right when tagged onto the end of
20647
the command line.  By adding the participle form of the verb, we
20648
make it clear that the default message stands alone as a new sentence
20649
(or sentence fragment, anyway) and is not meant as a missing
20650
continuation of the original command text.
20651
20652
</div>
20653
20654
<!------------------->
20655
<div class=entry>
20656
20657
"show iron key" - since the missing phrase form of this command has
20658
badness, this ends up being interpreted as "show key to iron", which
20659
is silly.  For command forms like this with two objects and no
20660
preposition, we should probably add a non-badness single-object
20661
grammar that asks for the missing prepositional phrase.  How we
20662
select the misisng-object phrasing over the two-object interpretation
20663
is unclear, though.
20664
20665
</div>
20666
20667
<!------------------->
20668
<div class=entry>
20669
20670
Parameterize the amount of time it takes for an actor to give an
20671
order to another actor.
20672
20673
</div>
20674
20675
<!------------------->
20676
<div class=entry>
20677
20678
try 'inflate raft and put it in bottle' - we don't get a blank line
20679
before the 'put it in bottle' response, presumably because it has
20680
an implicit command first
20681
20682
</div>
20683
20684
<!------------------->
20685
<div class=entry>
20686
20687
Floor/ceiling/walls for indoor rooms, ground/sky for outdoor rooms
20688
20689
</div>
20690
20691
<!------------------->
20692
<div class=entry>
20693
20694
Traverse the sense path for throwing an object at another object, and
20695
make the projectile land in the appropriate place when an intervening
20696
object prevents the throw from finishing.
20697
20698
</div>
20699
20700
<!------------------->
20701
<div class=entry>
20702
20703
Keep track of multiple logical results, and make comparisons based on
20704
the whole list.  Distinguish different reasons (using 'key' values)
20705
for different logical results with the same ranking.
20706
20707
<p>
20708
The idea is that if we have two objects that are both ranked the same
20709
way on one axis but are distinguishable on another axis, we want to
20710
consider the axis on which they're distinguishable.  For example, if
20711
we type "put silver coin in jar," and one jar is open and the other
20712
is closed, we want to pick the one that's open.  At the same time,
20713
they'll both be ranked as equivalently logical on the basis that
20714
neither is held by the actor.  We don't want the being-held status to
20715
override the open status, but we likewise don't want the open status
20716
to override the being-held status if both are open but only one is
20717
being held.  The solution is to ignore the equivalent being-held
20718
status when both objects have this same value, and to ignore the
20719
equivalent open status when both have the same value, but still
20720
consider these attributes when they differ.
20721
20722
</div>
20723
20724
<!------------------->
20725
<div class=entry>
20726
20727
Provide suitable default implementations for about 1.0e+6 verbs
20728
20729
</div>
20730
20731
<!------------------->
20732
<div class=entry>
20733
20734
"re-route" syntax - see, for example, keyring.iobjFor(AttachTo).
20735
Use asDobjFor and asIobjFor:
20736
20737
<p>
20738
<pre>
20739
   iobjFor(AttachTo) asIobjFor(PutOn)
20740
</pre>
20741
20742
</div>
20743
20744
<!------------------->
20745
<div class=entry>
20746
20747
For travel: actorStanding pre-condition that automatically extricates
20748
the actor from chairs and the like.  We must catch dangerous conditions
20749
in the verifier.
20750
20751
</div>
20752
20753
<!------------------->
20754
<div class=entry>
20755
20756
For missing iobj's, allow preposition in response:
20757
20758
<p>
20759
<pre>
20760
>dig in dirt
20761
What do you want to dig in it with?
20762
20763
>with shovel
20764
</pre>
20765
20766
</div>
20767
20768
<!------------------->
20769
<div class=entry>
20770
20771
Type/enter string/number on object
20772
20773
</div>
20774
20775
<!------------------->
20776
<div class=entry>
20777
20778
Type/turn to unquoted string?
20779
20780
</div>
20781
20782
<!------------------->
20783
<div class=entry>
20784
20785
In a two-object action, when assuming one object or the other, and
20786
then asking for the other, we should show the defaulted one before
20787
prompting:
20788
20789
<p>
20790
<pre>
20791
>ask
20792
(Bob)
20793
What do you want to ask him about?
20794
</pre>
20795
20796
</div>
20797
20798
<!------------------->
20799
<div class=entry>
20800
20801
For disambiguation, never pick a 'not obvious' over an illogical, because
20802
a 'not obvious' essentially counts as an illogical for the purposes of
20803
picking objects.
20804
20805
</div>
20806
20807
<!------------------->
20808
<div class=entry>
20809
20810
It might be good to eliminate the redundant default announcement in
20811
cases like this:
20812
20813
<p>
20814
<pre>
20815
>ask
20816
(asking Bob)
20817
What do you want to ask him about?
20818
20819
>watch
20820
(asking Bob)
20821
</pre>
20822
20823
</div>
20824
20825
<!------------------->
20826
<div class=entry>
20827
20828
It might be good to eliminate the participle when asking for a direct
20829
object of a two-object verb and the indirect object is not yet known:
20830
20831
<p>
20832
<pre>
20833
>ask
20834
(asking Bob)
20835
</pre>
20836
20837
<p>
20838
It would be better as simply
20839
20840
<p>
20841
<pre>
20842
>ask
20843
(Bob)
20844
</pre>
20845
20846
</div>
20847
20848
<!------------------->
20849
<div class=entry>
20850
20851
Turn x to string/number
20852
20853
</div>
20854
20855
<!------------------->
20856
<div class=entry>
20857
20858
Dials (turn, turn to)
20859
20860
</div>
20861
20862
<!------------------->
20863
<div class=entry>
20864
20865
Buttons (push)
20866
20867
</div>
20868
20869
<!------------------->
20870
<div class=entry>
20871
20872
Switches (turn on, turn off)
20873
20874
</div>
20875
20876
<!------------------->
20877
<div class=entry>
20878
20879
Levers (pull, push, move)
20880
20881
</div>
20882
20883
<!------------------->
20884
<div class=entry>
20885
20886
Doors
20887
20888
</div>
20889
20890
<!------------------->
20891
<div class=entry>
20892
20893
In the dark: should be able to list items you're holding by touch.
20894
20895
</div>
20896
20897
<!------------------->
20898
<div class=entry>
20899
20900
In the dark, 'look at' should indicate that it's the darkness that
20901
prevents an in-scope item from being inspected.
20902
20903
</div>
20904
20905
<!------------------->
20906
<div class=entry>
20907
20908
In the dark, inventory should do something better than say "you're
20909
empty-handed".
20910
20911
</div>
20912
20913
<!------------------->
20914
<div class=entry>
20915
20916
Climbables (such as stairs).  These should probably just be travel
20917
connectors that go up and down.
20918
20919
</div>
20920
20921
<!------------------->
20922
<div class=entry>
20923
20924
Check scope for preconditions - make sure we don't apply a command
20925
to an object not in scope by way of a precondition implicit command.
20926
For example, if you type "go north" in the dark, and there's a closed
20927
door that you can't see, you shouldn't be able to open the door by
20928
way of the travel precondition.
20929
20930
</div>
20931
20932
<!------------------->
20933
<div class=entry>
20934
20935
<pre>
20936
>go through passage
20937
>again
20938
</pre>
20939
20940
<p>
20941
This somehow keeps the old passage in scope.  Must need to check
20942
scope again for 'again'.
20943
20944
<p>
20945
(The problem is that the last action is hanging on to its cached
20946
resolver scope lists.  We simply need to drop the old resolvers
20947
so that we start the new command with new resolvers.)
20948
20949
</div>
20950
20951
<!------------------->
20952
<div class=entry>
20953
20954
climb up/climb down verbs
20955
20956
</div>
20957
20958
<!------------------->
20959
<div class=entry>
20960
20961
make sure we have makeOpen, makeClosed, makeLocked, makeUnlocked, etc. -
20962
in other words, encapsulate these types of state changes the same way
20963
moveInto encapsulates containment changes
20964
20965
</div>
20966
20967
<!------------------->
20968
<div class=entry>
20969
20970
Add an "inaccessible" verification failure - this would be more
20971
disapproving than any "illogical" level and would be used for
20972
"it's too dark" and "you can't reach that" types of failures.
20973
20974
</div>
20975
20976
<!------------------->
20977
<div class=entry>
20978
20979
The pre-condition execution sequence should probably be like this:
20980
20981
<p>
20982
<pre>
20983
  for (pass = 1 ; pass <= 2 ; ++pass)
20984
    run all verifiers
20985
    for each precondition
20986
      run this precondition, allowing implicit commands on pass 1 ONLY
20987
    if no implicit commands were executed
20988
      break
20989
</pre>
20990
20991
<p>
20992
This would ensure that side effects of an implicit command are re-tested
20993
through previous preconditions.  Each precondition would only be allowed
20994
to run its implicit command on pass 1 because this would prevent
20995
infinite loops from conflicting preconditions - on pass 2, if the
20996
condition isn't met by now, we'll assume it's not going to be, so
20997
we'll simply fail the command.
20998
20999
</div>
21000
21001
<!------------------->
21002
<div class=entry>
21003
21004
"actor, give x to me" should be handled as though it were "ask actor
21005
for x", via a replacement command.
21006
21007
</div>
21008
21009
<!------------------->
21010
<div class=entry>
21011
21012
actors: shouldn't allow taking possessions in general
21013
21014
</div>
21015
21016
<!------------------->
21017
<div class=entry>
21018
21019
Dark rooms: limit travel to adjacent lit locations?
21020
21021
</div>
21022
21023
<!------------------->
21024
<div class=entry>
21025
21026
Explicitly inherit base class vocabWords_ in initializeVocab() in
21027
us_eng.t.
21028
21029
</div>
21030
21031
<!------------------->
21032
<div class=entry>
21033
21034
touch/feel verbs
21035
21036
</div>
21037
21038
<!------------------->
21039
<div class=entry>
21040
21041
Add verb "listen" (both transitive and intransitive)
21042
21043
</div>
21044
21045
<!------------------->
21046
<div class=entry>
21047
21048
Add verb "smell" (transitive and intransitive)
21049
21050
</div>
21051
21052
<!------------------->
21053
<div class=entry>
21054
21055
Enterables
21056
21057
</div>
21058
21059
<!------------------->
21060
<div class=entry>
21061
21062
keys and doors: add options for boosting likelihood for keys:
21063
21064
<ul>
21065
<li>
21066
on the first successful use of a key, automatically boost the
21067
likelihood for future disambiguation using the key if an option is
21068
set (this might be the default option)
21069
21070
<li>
21071
if the author wants the player character to know from the outset
21072
which key goes with a door, the author can add the key to the
21073
lockable's knownKeyList - this can be useful for games with obvious
21074
key associations or key associations known from the outset to the
21075
player character (for example, if the PC has a key to their own
21076
house, the ought to know what the key opens)
21077
</ul>
21078
21079
</div>
21080
21081
<!------------------->
21082
<div class=entry>
21083
21084
locks and keys
21085
21086
</div>
21087
21088
<!------------------->
21089
<div class=entry>
21090
21091
lockable doors
21092
21093
</div>
21094
21095
<!------------------->
21096
<div class=entry>
21097
21098
Automatic key rings for unlocking doors - an "unlock" command with no
21099
indirect object automatically searches for a keyring in the actor's
21100
inventory, and automatically searches for a key on the keyring.
21101
21102
</div>
21103
21104
<!------------------->
21105
<div class=entry>
21106
21107
keyring: need to implicitly take keyring if not held when trying it
21108
21109
</div>
21110
21111
<!------------------->
21112
<div class=entry>
21113
21114
keyrings: message on success should be something like:
21115
21116
<p>
21117
(trying each key on the keyring, you find that the iron key unlocks the door)
21118
21119
</div>
21120
21121
<!------------------->
21122
<div class=entry>
21123
21124
keyring search: when we already know the correct key, we should just
21125
default it rather than search the keyring for it
21126
21127
</div>
21128
21129
<!------------------->
21130
<div class=entry>
21131
21132
implicit commands that use 'replace' should inherit original implicit
21133
status (try 's' from the stair bottom - we get an "unlocked" report
21134
for the replaced 'unlock door' command)
21135
21136
</div>
21137
21138
<!------------------->
21139
<div class=entry>
21140
21141
For Fixed, indirect the illogical messages through properties, to
21142
allow easier customization.
21143
21144
</div>
21145
21146
<!------------------->
21147
<div class=entry>
21148
21149
Whenever any message appears before a room description in a command
21150
sequence, show a blank line before the room description.  This applies
21151
especially to travel, but is generally desirable for any command that
21152
shows a room description.
21153
21154
</div>
21155
21156
<!------------------->
21157
<div class=entry>
21158
21159
Put iron key in duffel; unlock iron door - won't default the iron
21160
key, because the keyring takes precedence by virtue of being held.
21161
21162
<p>
21163
The problem is that the objHeld precondition is applying a likelihood
21164
of 80 because the iron key isn't held, and the held keys are getting
21165
100's.  Maybe we need to reduce the likelihood of any other keys or
21166
keyrings when the known key is present, but this seems like a poor
21167
special-case hack for a problem that is likely to arise in other
21168
contexts.
21169
21170
<p>
21171
To solve this, add a 'priority' to logical results.  Use low priority
21172
for precondition rankings, because these are inherently of lower
21173
importance than unique attributes of the objects themselves.
21174
21175
</div>
21176
21177
<!------------------->
21178
<div class=entry>
21179
21180
Add an 'exit only passage' to be used as the receiving end of things
21181
like trap doors, chutes, and so on.
21182
21183
</div>
21184
21185
<!------------------->
21186
<div class=entry>
21187
21188
Message travel connectors: simple connector that shows a message as the
21189
connector is traversed.
21190
21191
</div>
21192
21193
<!------------------->
21194
<div class=entry>
21195
21196
preserve the case of tokens in literal phrases
21197
21198
</div>
21199
21200
<!------------------->
21201
<div class=entry>
21202
21203
Light/dark changes should be noted at the end of each turn.
21204
21205
</div>
21206
21207
<!------------------->
21208
<div class=entry>
21209
21210
Light/dark changes should be noted before/after each daemon is
21211
dispatched.
21212
21213
</div>
21214
21215
<!------------------->
21216
<div class=entry>
21217
21218
21219
<pre>
21220
>move me to
21221
What do you want to move it to?
21222
</pre>
21223
21224
<p>
21225
Could we substitute "yourself" for "it" somehow?
21226
21227
</div>
21228
21229
<!------------------->
21230
<div class=entry>
21231
21232
Trap doors - in particular, the arrival message should indicate that the
21233
trap door automatically slams shut after the actor arrives.
21234
21235
</div>
21236
21237
<!------------------->
21238
<div class=entry>
21239
21240
Possessives - "take his box", "take bob's box"
21241
21242
</div>
21243
21244
<!------------------->
21245
<div class=entry>
21246
21247
possessives - problem with disambig:
21248
21249
<p>
21250
<pre>
21251
>get key's jar
21252
Which key's do you mean...
21253
</pre>
21254
21255
<p>
21256
That should just be 'which key do you mean', not 'which KEY'S'
21257
21258
</div>
21259
21260
<!------------------->
21261
<div class=entry>
21262
21263
possessives - plurals
21264
21265
</div>
21266
21267
<!------------------->
21268
<div class=entry>
21269
21270
possessives - five of bob's keys
21271
21272
</div>
21273
21274
<!------------------->
21275
<div class=entry>
21276
21277
possessives - bob's keys except the green one
21278
21279
</div>
21280
21281
<!------------------->
21282
<div class=entry>
21283
21284
get all of bob's keys except the rusty and iron ones - even when this
21285
is just one key, we should announce it as though it were a multiple
21286
object (so we need to set some flag)
21287
21288
</div>
21289
21290
<!------------------->
21291
<div class=entry>
21292
21293
possessives:
21294
21295
<p>
21296
<pre>
21297
>bob's
21298
unknown word ''s'
21299
</pre>
21300
21301
</div>
21302
21303
<!------------------->
21304
<div class=entry>
21305
21306
possessives - problem with disambig:
21307
21308
<p>
21309
<pre>
21310
>get key
21311
Which key do you mean...
21312
21313
>get bob's key
21314
The word ''s' is not necessary...
21315
</pre>
21316
21317
<p>
21318
The problem would seem to be that we don't handle 's in disambig
21319
responses and treat it as an unknown word.
21320
21321
</div>
21322
21323
<!------------------->
21324
<div class=entry>
21325
21326
<pre>
21327
>look under me
21328
You see nothing unusual under you.
21329
</pre>
21330
21331
<p>
21332
We should make that second 'you' into 'yourself' instead.  In general,
21333
can we change an objective case use of an object already used in the
21334
nominative should to a reflexive instead?
21335
21336
</div>
21337
21338
<!------------------->
21339
<div class=entry>
21340
21341
possessives - disambig response should allow 'bob's' as a choice,
21342
even if it's not offered
21343
21344
</div>
21345
21346
<!------------------->
21347
<div class=entry>
21348
21349
possessives - "get keys except bob's" - need special grammar for
21350
just a possessive in this context
21351
21352
</div>
21353
21354
<!------------------->
21355
<div class=entry>
21356
21357
<pre>
21358
>bob, x key
21359
Which key?
21360
21361
>quit
21362
This command cannot be directed to another character...
21363
</pre>
21364
21365
</div>
21366
21367
<!------------------->
21368
<div class=entry>
21369
21370
Distant items
21371
21372
</div>
21373
21374
<!------------------->
21375
<div class=entry>
21376
21377
Finish topic-verb implementation
21378
21379
</div>
21380
21381
<!------------------->
21382
<div class=entry>
21383
21384
Consider:
21385
21386
<p>
21387
<pre>
21388
>lock door
21389
(first closing the iron door)
21390
(with the iron key)
21391
Locked.
21392
</pre>
21393
21394
<p>
21395
The defaulted indirect object is misleading.  This should instead be:
21396
21397
<p>
21398
<pre>
21399
>lock door
21400
(with the iron key)
21401
(first closing the iron door)
21402
Locked.
21403
</pre>
21404
21405
<p>
21406
The problem comes from the fact that "Lock" has an objClosed
21407
precondition for keyed lockable; "Lock" doesn't need this
21408
precondition, because "LockWith" has it.  Removing the precondition
21409
will get the ordering right.
21410
21411
</div>
21412
21413
<!------------------->
21414
<div class=entry>
21415
21416
truncated adjectives seem worse than unknowns in ranking: 
21417
21418
<p>
21419
<pre>
21420
>type hello on typewri
21421
</pre>
21422
21423
</div>
21424
21425
<!------------------->
21426
<div class=entry>
21427
21428
do not filter the 'all' list with hideFromAll when looking for default
21429
objects
21430
21431
</div>
21432
21433
<!------------------->
21434
<div class=entry>
21435
21436
<pre>
21437
>get iron key
21438
You take the key and attach it to the keyring
21439
21440
>get keys
21441
brass key: You take and attach...
21442
rusty key: You take and attach...
21443
iron key: Taken.
21444
</pre>
21445
21446
<p>
21447
It's irritating that the last one is taken off the keyring.  Should
21448
we leave items out of plurals when we have multiple logical items of
21449
different logicalness?  (This isn't a completely academic problem,
21450
since you could in practice have a couple of new keys in a room that
21451
you want to pick up, without detaching keys you already have on the
21452
keyring.  One easy way to solve this would be to use a different
21453
command for detaching from the keyring - require 'take key off
21454
keyring', and say Illogical('if you want to take the key off the
21455
keyring, say so'); but this could be irritating when you just want to
21456
take the key off the keyring.
21457
21458
</div>
21459
21460
<!------------------->
21461
<div class=entry>
21462
21463
follow: should replace command with actual command used for last 
21464
observed travel; alternatively, reproduce the preconditions and
21465
verification for the travel via the connector
21466
21467
</div>
21468
21469
<!------------------->
21470
<div class=entry>
21471
21472
Player character vocabulary - either add switchPlayer to fiddle with
21473
the dictionary, or have some other way to route 'me' and 'my' to the
21474
current player character (using matchName, for example).
21475
21476
</div>
21477
21478
<!------------------->
21479
<div class=entry>
21480
21481
Move travel preconditions into the connectors after all.  Just create
21482
an openDoor precondition type that is instantiated with a specific
21483
door to open, rather than attaching it to a command object.
21484
21485
</div>
21486
21487
<!------------------->
21488
<div class=entry>
21489
21490
send bob into dark. follow bob into dark, then:
21491
21492
<p>
21493
<pre>
21494
>follow bob
21495
Bob is right here.
21496
21497
>bob, u
21498
You see no bob here.
21499
</pre>
21500
21501
</div>
21502
21503
<!------------------->
21504
<div class=entry>
21505
21506
<pre>
21507
>bob, n
21508
>g
21509
</pre>
21510
21511
<p>
21512
We're not checking to see if the actor is still in scope.
21513
21514
</div>
21515
21516
<!------------------->
21517
<div class=entry>
21518
21519
<pre>
21520
>n. open door.
21521
>close door and sit down
21522
</pre>
21523
--> endless loop - weird problem with token indices for 'sit down' part
21524
of grammar tree.  The token indices for the second predicate are for
21525
the entire command, strangely, so we think we need to parse the entire
21526
phrase again and again.
21527
21528
<p>
21529
This has something to do with the empty dobj noun phrase.  Same thing
21530
happens with 'close door and open' (which also has an empty dobj),
21531
but not with 'close door and look' (which takes no dobj) or 'close
21532
door and sit down on floor' (which has a non-empty dobj).
21533
21534
</div>
21535
21536
<!------------------->
21537
<div class=entry>
21538
21539
when changing sensory contexts, don't flush output; instead, consider
21540
sensory context when queueing reports, so that we simply don't queue
21541
a report unless it's visible in the sense context
21542
21543
</div>
21544
21545
<!------------------->
21546
<div class=entry>
21547
21548
when a door closes from the other side, show a message about it
21549
21550
</div>
21551
21552
<!------------------->
21553
<div class=entry>
21554
21555
Status line messages for nested rooms, sitting, lying
21556
21557
</div>
21558
21559
<!------------------->
21560
<div class=entry>
21561
21562
Standing needs to be able to specify what you're standing on in some
21563
cases, such as platforms.  Is it only the floor that won't?
21564
21565
</div>
21566
21567
<!------------------->
21568
<div class=entry>
21569
21570
when standing, make sure we move actor to room
21571
21572
</div>
21573
21574
<!------------------->
21575
<div class=entry>
21576
21577
when sitting/standing, make sure we do all the necessary work of
21578
travelTo
21579
21580
</div>
21581
21582
<!------------------->
21583
<div class=entry>
21584
21585
Chairs, beds (make Room not Fixed? or make a deeper base class for
21586
BaseRoom, with Room: Fixed, Room?)
21587
21588
</div>
21589
21590
<!------------------->
21591
<div class=entry>
21592
21593
sit/lie on floor: actor doesn't actually need to stand first, if the
21594
actor is already sitting/lying in the room.  In other words, if we're
21595
just changing from sitting to lying or vice versa, and not changing
21596
containers, we don't need an intermediate standing state.  We need
21597
something like standing-or-in-obj instead.
21598
21599
</div>
21600
21601
<!------------------->
21602
<div class=entry>
21603
21604
sit/lie/stand on - when checking that we can enter a nested room, make
21605
sure we're in the immediate container of the nested room
21606
21607
</div>
21608
21609
<!------------------->
21610
<div class=entry>
21611
21612
sit/lie: need to configure prep for 'on' vs 'in' (since we 'sit on'
21613
some things but 'sit in' other things, and likewise for 'lie on'
21614
vs 'lie in')
21615
21616
</div>
21617
21618
<!------------------->
21619
<div class=entry>
21620
21621
sit on floor, then sit on chair -> no intermediate 'stand'.  This might
21622
not be important, since it won't involve actual movement, but it's a 
21623
little weird, and it would be nice to make it consistent with the real
21624
nested rooms.
21625
21626
</div>
21627
21628
<!------------------->
21629
<div class=entry>
21630
21631
'sit on floor' doesn't work if run from a doubly-nested room (or deeper)
21632
21633
</div>
21634
21635
<!------------------->
21636
<div class=entry>
21637
21638
sit on armchair, then stand on dais: "already standing on the dais".
21639
Need to deal with an implied command that effects the change required
21640
of the main command.
21641
21642
</div>
21643
21644
<!------------------->
21645
<div class=entry>
21646
21647
Might want a precondition for travel more general than 'standing',
21648
to allow for standing in vehicles and on platforms
21649
21650
</div>
21651
21652
<!------------------->
21653
<div class=entry>
21654
21655
list actors in a nested room when describing the room
21656
21657
</div>
21658
21659
<!------------------->
21660
<div class=entry>
21661
21662
maximum seating capacity for a chair
21663
21664
</div>
21665
21666
<!------------------->
21667
<div class=entry>
21668
21669
in box: try 'e': "you can't do that from the main platform".
21670
21671
</div>
21672
21673
<!------------------->
21674
<div class=entry>
21675
21676
in box: in the dark, should probably have the enclosing room in scope
21677
21678
</div>
21679
21680
<!------------------->
21681
<div class=entry>
21682
21683
in box: when closed and we have light, definitely should have the
21684
enclosing room in scope
21685
21686
</div>
21687
21688
<!------------------->
21689
<div class=entry>
21690
21691
in box: should not be able to try to get out of box when we can't
21692
sense beyond the box - it should serve as top-level location for
21693
the purposes of the implied actions in this case
21694
21695
</div>
21696
21697
<!------------------->
21698
<div class=entry>
21699
21700
When in box, and box is closed, list contents of box as top-level
21701
contents of room.
21702
21703
</div>
21704
21705
<!------------------->
21706
<div class=entry>
21707
21708
Listing room contents should show contents of fixed items to any
21709
depth.  The first-level contents of anything not listed should by
21710
default be listed.
21711
21712
</div>
21713
21714
<!------------------->
21715
<div class=entry>
21716
21717
Vehicles
21718
21719
</div>
21720
21721
<!------------------->
21722
<div class=entry>
21723
21724
traveling - don't use actorStanding, but use travelerReady instead.
21725
If the traveler is an actor this turns into actorStanding (or whatever
21726
is appropriate for the actor); for a vehicle it's probably nothing, but
21727
could be used to check for things like the doors being closed on a car
21728
or seatbelts being fastened.
21729
21730
</div>
21731
21732
<!------------------->
21733
<div class=entry>
21734
21735
Vehicles: when PC is riding, we get no description of the new room
21736
21737
</div>
21738
21739
<!------------------->
21740
<div class=entry>
21741
21742
Vehicles: put tricycle on platform; get on tricycle; ride tricycle:
21743
we don't seem to move the tricycle off the platform first.
21744
21745
</div>
21746
21747
<!------------------->
21748
<div class=entry>
21749
21750
Vehicles: departing should use definite article
21751
21752
</div>
21753
21754
<!------------------->
21755
<div class=entry>
21756
21757
Vehicles: departing doesn't list riders (presumably they're out of
21758
scope by the time the departure message is generated; need to save
21759
sense info or something)
21760
21761
</div>
21762
21763
<!------------------->
21764
<div class=entry>
21765
21766
sample game: implement 'ride tricycle'
21767
21768
</div>
21769
21770
<!------------------->
21771
<div class=entry>
21772
21773
sample game: when getting on tricycle, mention how to ride it
21774
21775
</div>
21776
21777
<!------------------->
21778
<div class=entry>
21779
21780
Put x on floor: if we're in a nested room with a drop location that
21781
isn't the main room, we'll perform a "drop" in the nested room.  Should
21782
actually move to outermost room if possible.  (Maybe we need to leave
21783
the nested room as a precondition.)
21784
21785
</div>
21786
21787
<!------------------->
21788
<div class=entry>
21789
21790
Vehicles: need a convenient way to put up vehicle barriers, so that
21791
you can walk through a door but not ride through, and vice versa
21792
21793
</div>
21794
21795
<!------------------->
21796
<div class=entry>
21797
21798
'follow me' mode for an actor
21799
21800
</div>
21801
21802
<!------------------->
21803
<div class=entry>
21804
21805
recognize (in input) reflexive pronouns referring to target actor
21806
(bob, examine yourself)
21807
21808
</div>
21809
21810
<!------------------->
21811
<div class=entry>
21812
21813
Allow things to be placed out of reach from within nested rooms
21814
(canReachFromRoom).
21815
21816
</div>
21817
21818
<!------------------->
21819
<div class=entry>
21820
21821
change from LangThing to 'modify Thing', etc.
21822
21823
</div>
21824
21825
<!------------------->
21826
<div class=entry>
21827
21828
change "bob, tell me about x" into "me, ask bob about x"
21829
21830
</div>
21831
21832
<!------------------->
21833
<div class=entry>
21834
21835
'push/move dobj to iobj' - for things like building staircases ('push
21836
crate to window').  Synonyms might include 'push/move/put dobj under iobj'.
21837
21838
</div>
21839
21840
<!------------------->
21841
<div class=entry>
21842
21843
Fix follow problem: "bill cannot stand in closed box" is reported
21844
even though we're out of range of the sense.
21845
21846
</div>
21847
21848
<!------------------->
21849
<div class=entry>
21850
21851
Allow some types of nested rooms (platforms, booths) to be their own
21852
follow locations, so we can follow an actor into such a room
21853
21854
</div>
21855
21856
<!------------------->
21857
<div class=entry>
21858
21859
Might want to keep pronoun antecedents per actor.  When an issuer
21860
gives a command to a target, the target should copy all of the
21861
antecedents from the issuer.
21862
21863
</div>
21864
21865
<!------------------->
21866
<div class=entry>
21867
21868
for 'in' and 'out', by default ask for a direct object if there's
21869
no evident travel connection for the direction
21870
21871
</div>
21872
21873
<!------------------->
21874
<div class=entry>
21875
21876
remove all preconditions from noTravel, as we know travel will not occur
21877
and hence don't need to meet any conditions
21878
21879
</div>
21880
21881
<!------------------->
21882
<div class=entry>
21883
21884
'push obj north' (and other directions)
21885
21886
</div>
21887
21888
<!------------------->
21889
<div class=entry>
21890
21891
for "follow", track actors in vehicles as well as the vehicles
21892
themselves
21893
21894
</div>
21895
21896
<!------------------->
21897
<div class=entry>
21898
21899
'draggable' class, implementing a general framework for pushing
21900
objects from one room to another
21901
21902
</div>
21903
21904
<!------------------->
21905
<div class=entry>
21906
21907
add a push-travel barrier that works like the vehicle barrier, but
21908
for traveling while pushing objects
21909
21910
</div>
21911
21912
<!------------------->
21913
<div class=entry>
21914
21915
Change the barrier mechanism so that barriers are listed on the connector,
21916
rather than being part of the connector.  This is needed because the
21917
connector is in many cases directly addressable - putting the barrier
21918
in front of the connector as a proxy connector doesn't work when you
21919
can reach the connector directly, making an end run around the barrier.
21920
21921
</div>
21922
21923
<!------------------->
21924
<div class=entry>
21925
21926
Change the listing mechanism so that showList is a method of the
21927
ShowListInterface class, to simplify argument lists.
21928
21929
</div>
21930
21931
<!------------------->
21932
<div class=entry>
21933
21934
Handle nested grouping.  Use this for equivalents in groups.
21935
21936
</div>
21937
21938
<!------------------->
21939
<div class=entry>
21940
21941
For group listings, don't add a group when there's only one group due
21942
to equivalence.  We currently say this, which is awkward: "the jar
21943
contains two coins (two copper coins)."
21944
21945
</div>
21946
21947
<!------------------->
21948
<div class=entry>
21949
21950
Equivalent listings - eliminate as a separate special case and simply
21951
list equivalents using a listing group.  Add an Equivalent Group
21952
which implements a simple listing group for equivalents; by default,
21953
the group simply shows the count.
21954
21955
</div>
21956
21957
<!------------------->
21958
<div class=entry>
21959
21960
For our silver/gold/copper coins in the sample game, make sure the
21961
grouping mechanism can list like this: "eight coins (three silver and
21962
five gold)".  Note that the names in the parens leave off "coins" and
21963
just list the number and adjective.
21964
21965
</div>
21966
21967
<!------------------->
21968
<div class=entry>
21969
21970
Move all of the lister objects into the messages module, and eliminate
21971
the secondary indirection through the libMessages object.  Simply make
21972
the lister itself part of the messages module, and put the messages
21973
directly in the lister.
21974
21975
</div>
21976
21977
<!------------------->
21978
<div class=entry>
21979
21980
Get rid of the unnecessary list flags LIST_WORN and LIST_INVENTORY,
21981
replacing them with parameterization at the listing method level
21982
instead.
21983
21984
</div>
21985
21986
<!------------------->
21987
<div class=entry>
21988
21989
Use the generic list mechanism to list actors in a room.  By default,
21990
each actor simply lists separately, but it should be possible to
21991
group actors using the normal listing group mechanism ("Bob and Bill
21992
are at their desks", for example).
21993
21994
</div>
21995
21996
<!------------------->
21997
<div class=entry>
21998
21999
Can we make the disambig list use the normal listing mechanism?
22000
<no, probably not worth it>
22001
22002
</div>
22003
22004
<!------------------->
22005
<div class=entry>
22006
22007
Add a "specialDesc", similar to initDesc but for more general purposes.
22008
specialDesc should turn into initDesc when initDesc is applicable.
22009
22010
</div>
22011
22012
<!------------------->
22013
<div class=entry>
22014
22015
add "the former" and "the latter" as disambiguation responses
22016
22017
</div>
22018
22019
<!------------------->
22020
<div class=entry>
22021
22022
For nested rooms, break out the "staging location" test from
22023
checkActorReadyToEnterNestedRoom into a separate routine.  Use a
22024
list of possible staging areas given by a separate property for
22025
easier overriding.
22026
22027
</div>
22028
22029
<!------------------->
22030
<div class=entry>
22031
22032
For nested rooms, use a separate "exit destination" property for the
22033
destination of a GetOutOf action, rather than assuming that we always
22034
move to the enclosing location.
22035
22036
</div>
22037
22038
<!------------------->
22039
<div class=entry>
22040
22041
Add a "high nested room" that can't be entered except from particular
22042
staging areas due to height.  These is a fairly trivial
22043
specialization: first, don't solve the problem using implicit
22044
commands unless the actor has already solved it before; second, the
22045
default failure message is something like "you can't enter that from
22046
here; it's too high up."
22047
22048
</div>
22049
22050
<!------------------->
22051
<div class=entry>
22052
22053
Rename the '*predicate*' production classes to '*command*'
22054
22055
</div>
22056
22057
<!------------------->
22058
<div class=entry>
22059
22060
Base all command (formerly predicate) classes on a common CommandProd
22061
base class
22062
22063
</div>
22064
22065
<!------------------->
22066
<div class=entry>
22067
22068
Add a resolveAction method to the command classes.  This method
22069
retrieves the action from the command.  In English, this simply
22070
retrieves the 'predicate' match tree object, which is always based on
22071
action; other languages, especially those that use case markers
22072
rather than word order to encode phrase-role information, can
22073
customize this behavior appropriately for their grammatical systems.
22074
22075
</div>
22076
22077
<!------------------->
22078
<div class=entry>
22079
22080
When scanning command parse matches, we can immediately eliminate
22081
any match for which resolveAction fails to find a valid action.
22082
22083
</div>
22084
22085
<!------------------->
22086
<div class=entry>
22087
22088
Use separate listers for room/object contents lists and inventory lists.
22089
Use separate show-list-item methods for inventory items.
22090
22091
</div>
22092
22093
<!------------------->
22094
<div class=entry>
22095
22096
For keyrings, show contents of keyring in room/object/inventory contents
22097
as a sublist:  a keyring (attached to which are an iron key and a bronze
22098
key)...
22099
22100
</div>
22101
22102
<!------------------->
22103
<div class=entry>
22104
22105
Allow queuing pending actions for an actor, not just token lists.
22106
Make it possible to insert a pending action at the beginning of the
22107
queue (for continuation actions).
22108
22109
</div>
22110
22111
<!------------------->
22112
<div class=entry>
22113
22114
Use a separate listing flag (isListedInInventory) for inventory
22115
list inclusion.  For actors, make this true by default, even though
22116
actors are not listed in room descriptions.
22117
22118
</div>
22119
22120
<!------------------->
22121
<div class=entry>
22122
22123
Dispenser and Dispensable, for matchbooks and the like
22124
22125
</div>
22126
22127
<!------------------->
22128
<div class=entry>
22129
22130
Collective objects for cases like "book of matches" and "matches" -
22131
when we type "take matches," we should interpret this as the book of
22132
matches (i.e., "matches" == singular) rather than as the individual
22133
matches ("matches" == plural).
22134
22135
</div>
22136
22137
<!------------------->
22138
<div class=entry>
22139
22140
Matches - flammable objects that are self-igniting
22141
22142
</div>
22143
22144
<!------------------->
22145
<div class=entry>
22146
22147
Matchbooks
22148
22149
</div>
22150
22151
<!------------------->
22152
<div class=entry>
22153
22154
Include a checksum in saved state files, and check at start of load.
22155
This will help avoid attempting to restore a file that was corrupted.
22156
22157
</div>
22158
22159
<!------------------->
22160
<div class=entry>
22161
22162
Add a tentative pre-resolution pass, for the later-resolved object of
22163
a two-object action, that runs before the resolution of the
22164
earlier-resolved object.  Don't perform full resolution on this pass;
22165
specifically, don't count any problems against the ranking results,
22166
and don't ask for help interactively.  
22167
22168
<p>
22169
Make use of this information in 'verify' routines for the
22170
earlier-resolved objects when applicable.  For example, for "take
22171
<dobj> from <iobj>", we resolve the indirect object first, so we
22172
don't know the final dobj resolution when resolving the iobj; so, use
22173
the tentative information so that we can rule an iobj illogical if
22174
there's no tentative dobj inside the proposed iobj.
22175
22176
</div>
22177
22178
<!------------------->
22179
<div class=entry>
22180
22181
Might want to clean up the other-object business in askMissingObject
22182
and related routines.  This scheme doesn't feel properly generalized.
22183
For that matter, we might want to rethink the whole scheme so that
22184
it's subclassed by and handled in the action classes, rather than
22185
parameterized, since the parameterization scheme seems hokey and
22186
brittle.
22187
22188
</div>
22189
22190
<!------------------->
22191
<div class=entry>
22192
22193
Remove the otherObjectList and otherObjectWhich stuff when we've
22194
cleaned up the corresponding code.  This information should now be
22195
available via the tentative resolution lists instead.
22196
22197
</div>
22198
22199
<!------------------->
22200
<div class=entry>
22201
22202
When lighting a match as part of an implied command, reduce the burn
22203
time by one turn - this ensures that lighting the match as part of
22204
another action won't artificially extend the match's burn time.
22205
22206
</div>
22207
22208
<!------------------->
22209
<div class=entry>
22210
22211
candles, torches, oil lanterns - flammable objects that must be lit with
22212
another item, such as a match
22213
22214
</div>
22215
22216
<!------------------->
22217
<div class=entry>
22218
22219
defaults: when there are two or more equivalent items that could be
22220
used as defaults, pick one arbitrarily
22221
22222
</div>
22223
22224
<!------------------->
22225
<div class=entry>
22226
22227
for implied transfers into a bag of holding, put the indirect object
22228
of "take from" last in the affinity list
22229
22230
</div>
22231
22232
<!------------------->
22233
<div class=entry>
22234
22235
for implied transfers into a bag of holding, other things being equal,
22236
transfer the least recently acquired object first
22237
22238
</div>
22239
22240
<!------------------->
22241
<div class=entry>
22242
22243
food items
22244
22245
</div>
22246
22247
<!------------------->
22248
<div class=entry>
22249
22250
Change the logic of checkActorInStagingLocation so that it doesn't
22251
assume that we can reach a staging location just because we're
22252
indirectly in the location.  Instead, add a "choose staging location"
22253
method so that rooms can override the staging location chooser with
22254
appropriate special-case code when needed.
22255
22256
</div>
22257
22258
<!------------------->
22259
<div class=entry>
22260
22261
Add issuing actor and target actor parameters to resolveAction(), so
22262
that the resolver can tell what reflexive pronoun phrases mean.  (In
22263
many languages, reflexive constructions are structurally part of some
22264
predicates, and affect the meaning of the predicate, so the identity
22265
of the speaker and of the subject must sometimes be known to
22266
correctly determine the interpretation of the predicate structure.)
22267
22268
</div>
22269
22270
<!------------------->
22271
<div class=entry>
22272
22273
sample game: reject just plain "match" in the matchbook's matchName
22274
22275
</div>
22276
22277
<!------------------->
22278
<div class=entry>
22279
22280
touch scope: include contents of matchbooks and keyrings, so that
22281
these can be used even in the dark
22282
22283
</div>
22284
22285
<!------------------->
22286
<div class=entry>
22287
22288
Add an associated odor and sound property to each Thing.  This points
22289
to an object that encapsulates the object's sensory emanations.  Always
22290
add these objects to scope when the associated objects are in scope,
22291
with the same properties.
22292
22293
<p>
22294
Make "listen to x" and "smell x" defer to the associated objects.
22295
22296
<p>
22297
For scoping, a sound or smell doesn't have to place the main object
22298
in scope, but rather can just put the intangible sensory emanation in
22299
scope.  For example, if an alarm clock is buzzing, the 'buzzing
22300
sound' object would be in scope but not the alarm clock itself.  (On
22301
the other hand, some sounds, like a ringing phone, might be
22302
sufficiently distinctive as to place the main object in scope.  But
22303
for those cases we can simply associate the sound/smell with the main
22304
object.)
22305
22306
</div>
22307
22308
<!------------------->
22309
<div class=entry>
22310
22311
We need different odor/sound descriptions for different situations:
22312
22313
<p>
22314
<pre>
22315
>listen to phone
22316
It's ringing.
22317
<i>==> phone.soundDesc</i>
22318
22319
>listen to ring [phone visible]
22320
It's coming from the phone.
22321
<i>==> sound.soundWithSource</i>
22322
22323
>listen to ring [phone not visible]
22324
It sounds like a phone.
22325
<i>==> sound.soundWithoutSource</i>
22326
22327
>look [phone visible]
22328
...
22329
The phone is ringing.
22330
<i>==> sound.soundHereWithSource</i>
22331
22332
>look [phone not visible]
22333
...
22334
You can hear what sounds like a phone ringing.
22335
<i>==> sound.soundHereWithoutSource</i>
22336
</pre>
22337
22338
</div>
22339
22340
<!------------------->
22341
<div class=entry>
22342
22343
Don't open a footnote when the PC isn't seeing the text with the
22344
footnote reference.
22345
22346
</div>
22347
22348
<!------------------->
22349
<div class=entry>
22350
22351
Add sense emanations to inventory displays.
22352
22353
</div>
22354
22355
<!------------------->
22356
<div class=entry>
22357
22358
For sound/smell objects, add options to control ongoing announcements
22359
of sensory emanations:
22360
22361
<ul>
22362
<li>always show on room description, or only show on
22363
explicit "look" descriptions (and corresponding sense commands -
22364
"smell", "listen")
22365
22366
<li>show every n clock ticks
22367
22368
<li>show every n clock ticks for m iterations, then go
22369
to a secondary message every p clock ticks (for something like "the
22370
phone is still ringing").
22371
</ul>
22372
22373
</div>
22374
22375
<!------------------->
22376
<div class=entry>
22377
22378
Room descriptions should be differentiated according to whether we're
22379
explicitly looking or merely entering a new room.
22380
22381
</div>
22382
22383
<!------------------->
22384
<div class=entry>
22385
22386
When a noise's or odor's source is not visible, and the object is
22387
examined (via "examine", or via "listen to" or "smell" or whatever),
22388
it might be desirable in many cases to show the <i>apparent</i> source,
22389
which is to say the visually opaque obstructor, and describe the
22390
sound/odor as coming from inside/outside/behind/whatever the
22391
obstructor.
22392
22393
<p>
22394
The obstructor can be easily found with
22395
gActor.findOpaqueObstructor(sight, obj) (where 'obj' is the noise or
22396
odor object).  Once the obstructor is found, we'll have to generate
22397
an appropriate message, which will require a new method parallel to
22398
obs.cannotReachObject(obj) - perhaps we could call it
22399
obs.describeSoundObstructor(obj) etc - which would display "The
22400
ringing seems to be coming from inside the box" and the like.
22401
22402
<p>
22403
This entire mechanism would not be used when the obstructor itself
22404
cannot be seen, such as in the dark.
22405
22406
</div>
22407
22408
<!------------------->
22409
<div class=entry>
22410
22411
Consider:
22412
22413
<p>
22414
<pre>
22415
>look
22416
...
22417
You can hear what sounds like a phone ringing.
22418
22419
>listen to ring
22420
It sounds like a phone.
22421
22422
>x phone
22423
You don't see any phone.
22424
</pre>
22425
22426
<p>
22427
It would be better if that last line were:
22428
22429
<p>
22430
<pre>
22431
>x phone
22432
You can hear a phone ringing, but you can't see it.
22433
</pre>
22434
22435
<p>
22436
To deal with this, adjust the touchObj and objVisible preconditions
22437
so that it provides better feedback for an object that can be heard
22438
but not seen.
22439
22440
</div>
22441
22442
<!------------------->
22443
<div class=entry>
22444
22445
Write a common main() that most games will use, with appropriate
22446
hooks for showing the introductory text and so on.  Or, perhaps
22447
better, write a standard initialization routine that the game's
22448
main() can call.
22449
22450
</div>
22451
22452
<!------------------->
22453
<div class=entry>
22454
22455
Provide an author-configurable option to process multiple orders to
22456
NPC's synchronously - so, if you say "bob, go north, get all, go
22457
south", the PC doesn't get a command line prompt again until Bob
22458
finishes the whole set of commands.
22459
22460
</div>
22461
22462
<!------------------->
22463
<div class=entry>
22464
22465
It might be worth considering making the disambiguation responses for
22466
&noMatchDisambig and &disambigOrdinalOutOfRange more interactive.
22467
Currently, if you give an invalid response to a disambig question,
22468
you get an error and no chance to retry.  Something like this might
22469
be more intuitive:
22470
22471
<p>
22472
<pre>
22473
>take ball
22474
Which ball, the red ball, or the green ball?
22475
22476
>third
22477
There weren't that many choices - did you mean the red ball, or the
22478
green ball?
22479
22480
>orange
22481
That wasn't one of the choices - did you mean the red ball, or the
22482
green ball?
22483
</pre>
22484
22485
<p>
22486
However, if the response looks like a valid response but doesn't give
22487
us a match, and it also looks syntactically like a valid new command,
22488
treat it as a new command.
22489
22490
</div>
22491
22492
<!------------------->
22493
<div class=entry>
22494
22495
Generic script objects:  an object for which we call a method automatically
22496
each turn it's active.  We'd keep a counter that we'd automatically advance
22497
on each call.  We should probably use this generic object to implement
22498
text lists.
22499
22500
</div>
22501
22502
<!------------------->
22503
<div class=entry>
22504
22505
Generic text lists:  an object that encapsulates a list of messages
22506
to display, one per turn.
22507
22508
<p>
22509
Text lists should be linkable to a common counter object, so that the
22510
lists are synchronized on the same counter.  This lets you have separate
22511
lists for each room, but keep the timeline in each list the same.
22512
22513
<p>
22514
It should be possible to associate a text list object with a room instead
22515
of coding the room's text list in-line in the room.
22516
22517
</div>
22518
22519
<!------------------->
22520
<div class=entry>
22521
22522
Room text lists:  a list of atmosphere messages we cycle through while
22523
the player is in the room.  This should be totally automatic, so you
22524
just program the list and the library automatically sets up a daemon
22525
to run through the messages.
22526
22527
</div>
22528
22529
<!------------------->
22530
<div class=entry>
22531
22532
When describing an object, show the special descriptions for any contents
22533
of the object, just as we would list them in room descriptions.  This
22534
lets us see the special descriptions for contents, without having to
22535
write any additional descriptive code in the container.
22536
22537
</div>
22538
22539
<!------------------->
22540
<div class=entry>
22541
22542
consider:
22543
22544
<p>
22545
<pre>
22546
>take coin
22547
Which coin, silver or gold?
22548
</pre>
22549
22550
<p>
22551
We should probably keep the copper one in the list.  In particular,
22552
we probably shouldn't remove an item from consideration for
22553
disambiguation just because it's less likely - once we've determined
22554
that the noun phrase is ambiguous, we should offer all logical
22555
matches, even when they're less likely.
22556
22557
</div>
22558
22559
<!------------------->
22560
<div class=entry>
22561
22562
consider:
22563
22564
<p>
22565
<pre>
22566
>take coinc
22567
Which coin...?
22568
22569
>take tricyc
22570
The word 'tricyc' is not necessary in this story.
22571
22572
>take tricyc
22573
Taken.
22574
</pre>
22575
22576
<p>
22577
For some reason, truncated words are treated as misspellings when they
22578
appear in disambiguation responses.
22579
22580
</div>
22581
22582
<!------------------->
22583
<div class=entry>
22584
22585
Can we cache sense information to speed up resolution a bit?  In
22586
particular, we should be able to cache sense information during the
22587
noun phrase resolution and verification steps, since these do not
22588
normally involve any game state changes; once execution begins,
22589
though, caching should be turned off.  (This is probably the optimal
22590
set of trade-offs: on the one hand, the game and library should
22591
never have to worry about cache invalidation - the library only needs
22592
to turn caching on before starting the parsing phase and then turn
22593
caching off before beginning the execution phase of a command; on
22594
the other hand, we should derive substantial efficiency from caching
22595
during the parsing phase, because this phase in particular tends to
22596
evaluate a lot of sense information.
22597
22598
<p>
22599
(Experimental code has been added, conditionally compiled based on
22600
the SENSE_CACHE macro.  We'll leave it on for the time being to get
22601
some experience with it to see how well it works.)
22602
22603
</div>
22604
22605
<!------------------->
22606
<div class=entry>
22607
22608
Preparsing
22609
22610
</div>
22611
22612
<!------------------->
22613
<div class=entry>
22614
22615
Just-out-of-reach containers.  Create a container type that puts its
22616
contents in the distance for 'touch' purposes.  This can be used for
22617
things like items on the ceiling.  We'll need a way to make this vary
22618
depending on the source object, so that, for example, something could
22619
be out of reach for an actor standing in the room but in reach if the
22620
actor stands on a desk.
22621
22622
</div>
22623
22624
<!------------------->
22625
<div class=entry>
22626
22627
When using 'again' with a command that had an interactive
22628
disambiguation response, the response 'that wasn't one of the
22629
choices' is not appropriate since the player doesn't get to respond.
22630
22631
</div>
22632
22633
<!------------------->
22634
<div class=entry>
22635
22636
cache touch paths (and canTouch information) the same way we cache
22637
sense paths
22638
22639
</div>
22640
22641
<!------------------->
22642
<div class=entry>
22643
22644
For OutOfReach containers, we shouldn't be able to touch the
22645
container itself, since not only the contents but the container
22646
itself is meant to be out of reach.  To do this, add a PathTo
22647
traversal for the last item in a path (and while we're at it, add the
22648
symmetrical PathFrom for the first item in the path), and in
22649
OutOfReach's checkTouchViaPath, treat PathTo the same as PathIn.
22650
22651
</div>
22652
22653
<!------------------->
22654
<div class=entry>
22655
22656
'down' from a platform should be 'get off platform' by default
22657
22658
</div>
22659
22660
<!------------------->
22661
<div class=entry>
22662
22663
add 'debug' verb (to break into the debugger)
22664
22665
</div>
22666
22667
<!------------------->
22668
<div class=entry>
22669
22670
Real-time events: on save/restore, adjust system clock basis to keep
22671
everything in sync
22672
22673
</div>
22674
22675
<!------------------->
22676
<div class=entry>
22677
22678
Real-time events: design a class for the events
22679
22680
</div>
22681
22682
<!------------------->
22683
<div class=entry>
22684
22685
Real-time events: integrate with the scheduler and command reader
22686
22687
</div>
22688
22689
<!------------------->
22690
<div class=entry>
22691
22692
Real-time events: when an interruption occurs, catch any output and
22693
automatically cancel the interrupted input
22694
22695
</div>
22696
22697
<!------------------->
22698
<div class=entry>
22699
22700
Fix problem with quoted strings in literal phrases (as in 'type
22701
"hello" on typewriter')
22702
22703
</div>
22704
22705
<!------------------->
22706
<div class=entry>
22707
22708
Fix problem with 'throw': it's illogical to throw something at an
22709
object within the object being thrown
22710
22711
</div>
22712
22713
<!------------------->
22714
<div class=entry>
22715
22716
Change all of the exclusion list phrases to terminalNounPhrase rules -
22717
otherwise, when they exclude everything, they get misinterpreted as
22718
((all but x and y) and z) which turns into (z and z).  Everything with
22719
a 'but' should turn into a terminalNounPhrase, just like the plain
22720
'all but &lt;list&gt;' rule.
22721
22722
</div>
22723
22724
<!------------------->
22725
<div class=entry>
22726
22727
Make 'me' symmetric with 'yourself' in the grammar.  In particular,
22728
'me' should refer to the issuing actor, which is not necessarily the
22729
player character.
22730
22731
</div>
22732
22733
<!------------------->
22734
<div class=entry>
22735
22736
fix problem with "yourself, jump"
22737
22738
</div>
22739
22740
<!------------------->
22741
<div class=entry>
22742
22743
For chairs and the like, we might want to consider an object owned
22744
by an actor if the actor is occupying the object (so, "bob's chair"
22745
is the chair bob is sitting on).
22746
22747
</div>
22748
22749
<!------------------->
22750
<div class=entry>
22751
22752
When taking an item, reduce the likelihood that an item being carried
22753
by another actor is the one being taken.
22754
22755
</div>
22756
22757
<!------------------->
22758
<div class=entry>
22759
22760
Provide a way of distinguishing lit and unlit equivalents in a list.
22761
Likewise for worn and unworn objects.  Should probably add another
22762
list group object after the equivalent grouper, and in this object
22763
we should provide one group for lit objects and another for unlit.
22764
The desired output is something like this:
22765
22766
<p>
22767
<pre>
22768
  You are carrying three matches (one lit), two flashlights (one
22769
  providing light).
22770
</pre>
22771
22772
</div>
22773
22774
<!------------------->
22775
<div class=entry>
22776
22777
Move the inheritNext into the behavior as the default native 'inherit'
22778
instruction.  Remove inheritNext from library source files.
22779
22780
</div>
22781
22782
<!------------------->
22783
<div class=entry>
22784
22785
the dagger shouldn't show up in the 'x desk' description when the
22786
dagger's initial message is still being shown
22787
22788
</div>
22789
22790
<!------------------->
22791
<div class=entry>
22792
22793
Add macros to make grammar rules for predicates easier to read.
22794
22795
</div>
22796
22797
<!------------------->
22798
<div class=entry>
22799
22800
Improve the module names (adv3g -> parser.t, adv3v -> verbs.t, etc)
22801
22802
</div>
22803
22804
<!------------------->
22805
<div class=entry>
22806
22807
provide .t3m, .tdc for sample game with proper directory set-up
22808
22809
</div>
22810
22811
<!------------------->
22812
<div class=entry>
22813
22814
accept 'all &lt;adj&gt;' and the like
22815
22816
</div>
22817
22818
<!------------------->
22819
<div class=entry>
22820
22821
build the #include file list in Workbench automatically when creating
22822
a project, and when explicitly asked via a new command "scan source
22823
files for #include"
22824
22825
</div>
22826
22827
<!------------------->
22828
<div class=entry>
22829
22830
compiler: warn on finding a backslash outside quoted text in front of
22831
anything but a newline
22832
22833
</div>
22834
22835
<!------------------->
22836
<div class=entry>
22837
22838
Add a simpler, more structured way to add a single paragraph break.
22839
Use a new pseudo-tag, "<.p>", to indicate a paragraph break; process
22840
this tag just before writing output to the console.
22841
22842
</div>
22843
22844
<!------------------->
22845
<div class=entry>
22846
22847
All library input functions should coordinate with command reports to
22848
turn off output capturing.
22849
22850
</div>
22851
22852
<!------------------->
22853
<div class=entry>
22854
22855
Add a finishGame() function offering restart/restore/undo/quit options
22856
22857
</div>
22858
22859
<!------------------->
22860
<div class=entry>
22861
22862
Build a proper set of Workbench sample games
22863
22864
</div>
22865
22866
<!------------------->
22867
<div class=entry>
22868
22869
Freeze the real-time clock while we're waiting for inputFile results,
22870
while we're saving/restoring a file, and while we're waiting for an
22871
inputLine when real-time events are not allowed.  All of these should
22872
be considered to be outside the normal real-time flow of the game,
22873
so none of them should consume any game real-time.
22874
22875
</div>
22876
22877
<!------------------->
22878
<div class=entry>
22879
22880
In showList: mix groups and singles in the original order of lst,
22881
rather than displaying groups and then singles separately.  This is
22882
important because we're not preserving the original ordering when
22883
the list is sorted and it has subgroups.  We can't guarantee
22884
that we'll preserve the sorting order, of course, since grouping
22885
could put together items that weren't consecutive in the sorting
22886
order, so let grouping prevail when there's a conflict; but when
22887
possible, keep the order the same.  To do this, we should have
22888
a single loop that traverses the original lst; for each item, if
22889
it's a single, show the single, otherwise show its group.  Only
22890
show the group for the first item in the group; once we match a
22891
group, mark the group as used so we don't show it again.
22892
22893
</div>
22894
22895
<!------------------->
22896
<div class=entry>
22897
22898
'+' should consistently concatenate individual items from a
22899
collection on the right-hand side, whether the right-hand side is a
22900
list, vector, or array
22901
22902
</div>
22903
22904
<!------------------->
22905
<div class=entry>
22906
22907
'+' and '-' should work with an Array as the left-hand side
22908
22909
</div>
22910
22911
<!------------------->
22912
<div class=entry>
22913
22914
Delete class Array.  We'll have to change the function object stuff
22915
to use Vector instead of Array.
22916
22917
</div>
22918
22919
<!------------------->
22920
<div class=entry>
22921
22922
Make Vector+val and Vector-val return new objects - do not modify the
22923
original vector in place
22924
22925
</div>
22926
22927
<!------------------->
22928
<div class=entry>
22929
22930
add Vector.appendAll() - appends list elements in-place; maybe
22931
Vector.removeValue() and Vector.removeAllValues() to do '-' in-place
22932
22933
</div>
22934
22935
<!------------------->
22936
<div class=entry>
22937
22938
LookupTable.forEach: remove the 'key' argument to make its interface
22939
the same as everything else's.
22940
22941
</div>
22942
22943
<!------------------->
22944
<div class=entry>
22945
22946
Everything with a forEach: add a forEachAssoc(key, val) method alongside
22947
forEach.
22948
22949
</div>
22950
22951
<!------------------->
22952
<div class=entry>
22953
22954
for Openable, if the object isn't transparent looking in, implicitly
22955
open the object for "look in"
22956
22957
</div>
22958
22959
<!------------------->
22960
<div class=entry>
22961
22962
Iterators: add getCurVal and getCurKey methods.
22963
22964
</div>
22965
22966
<!------------------->
22967
<div class=entry>
22968
22969
Fix bug: 'listen' or 'smell' shows no response when there are things
22970
that nominally have Noise/Odor associations, but none of the Noise/Odor
22971
objects actually has anything to say at the moment.
22972
22973
</div>
22974
22975
<!------------------->
22976
<div class=entry>
22977
22978
Dictionary: add a way to iterate over the entries in the dictionary.
22979
22980
</div>
22981
22982
<!------------------->
22983
<div class=entry>
22984
22985
For inputManager.inputLineBegin and inputLineEnd, use a new style tag
22986
"<.inputline>" rather than coding "<font face=tads-input>" directly.
22987
This makes it easier for a game to customize the input font setting.
22988
22989
</div>
22990
22991
<!------------------->
22992
<div class=entry>
22993
22994
Add access to the "restore code" (the second argument passed to
22995
restoreGame()) for PostRestoreObject instances by adding the value as
22996
a class property of PostRestoreObject.
22997
22998
</div>
22999
23000
<!------------------->
23001
<div class=entry>
23002
23003
Change the Thing template that ends with "desc" @location to end
23004
instead with @location "desc" (i.e., reverse the desc and location
23005
property order).  Since "desc" can be lengthy, putting the location
23006
first will make the template more readable.
23007
23008
</div>
23009
23010
<!------------------->
23011
<div class=entry>
23012
23013
Add before/after command separation messages in libMessages, to allow
23014
for finer-grained control over the formatting of command responses.
23015
23016
</div>
23017
23018
<!------------------->
23019
<div class=entry>
23020
23021
Check dark travel before checking any barriers - move the call to
23022
gActor.checkDarkTravel into the TravelConnector methods that call
23023
gActor.travelTo, since this must be called as a separate phase before
23024
the travel connectors do any of their other work.
23025
23026
</div>
23027
23028
<!------------------->
23029
<div class=entry>
23030
23031
Make Illogical() the most illogical ranking, and make IllogicalNow()
23032
slightly less illogical (i.e., invert the old ordering of Illogical
23033
and IllogicalNow).
23034
23035
</div>
23036
23037
<!------------------->
23038
<div class=entry>
23039
23040
Add Action.setMessageParam(), to allow message processors to set
23041
their own special message parameters that they can use in expansion
23042
text.  This would be better than constructing messages partially with
23043
the "{it obj/him}" mechanism and brute-force string concatenation,
23044
because it would allow the concatenated bits to participate in the
23045
same processing steps, such as reflexive pronoun conversions.
23046
23047
<p>
23048
Add a macro (gMessageParams) to simplify the syntax for adding new
23049
message parameters.
23050
23051
</div>
23052
23053
<!------------------->
23054
<div class=entry>
23055
23056
"x me" doesn't work in dark (target actor of a command should always
23057
be in scope)
23058
23059
</div>
23060
23061
<!------------------->
23062
<div class=entry>
23063
23064
Remove 'actorResolved' check from execCommandTokens - this check is
23065
vestigial (it stopped being necessary when we started pulling out the
23066
actor phrase after resolution and re-parsing the rest of the command),
23067
and makes it impossible to have multiple levels of indirection, as in
23068
"tell bob to tell bill to go north".
23069
23070
</div>
23071
23072
<!------------------->
23073
<div class=entry>
23074
23075
Refactor FirstCommandProdWithActor (parser.t) to move the actor resolution
23076
stuff into a separate CommandProdWithActor that FCPWA inherits from.
23077
23078
</div>
23079
23080
<!------------------->
23081
<div class=entry>
23082
23083
<pre>
23084
>bob, get ball
23085
Which ball?
23086
23087
>z
23088
Bob waits...
23089
</pre>
23090
23091
<p>
23092
The "z" should have a default target of the player character, not Bob.
23093
23094
</div>
23095
23096
<!------------------->
23097
<div class=entry>
23098
23099
Allow things like "tell bill to tell bob to go north".  In particular,
23100
fix execCommandTokens so that it doesn't assume that only one actor can
23101
be resolved per command.
23102
23103
</div>
23104
23105
<!------------------->
23106
<div class=entry>
23107
23108
Keep first-on-line information in the PendingCommandInfo.  (This requires
23109
changing the interfaces to all of the Actor routines that create pending
23110
command info objects: addPendingCommand, addFirstPendingCommand,
23111
addPendingAction, addFirstPendingAction.)
23112
23113
</div>
23114
23115
<!------------------->
23116
<div class=entry>
23117
23118
Add a noun-list grammar rule for singleNoun, so that if we match a
23119
noun list in a place where a single noun is grammatically required,
23120
we can generate an appropriate message rather than failing to match
23121
grammar.
23122
23123
<p>
23124
Symptoms fixed: "ask bob and bill about box" -> "you see no bob and
23125
bill here"; "give coins to bob and bill" -> "you see no coins to here".
23126
23127
</div>
23128
23129
<!------------------->
23130
<div class=entry>
23131
23132
Add a point-of-view argument to BasicLocation.lookAround, so that a
23133
room can be described from a point of view other than the actor doing
23134
the looking.
23135
23136
</div>
23137
23138
<!------------------->
23139
<div class=entry>
23140
23141
Fix: paragraph break in response to getting out of white box while
23142
the box is closed (in the platform room).  (The last report -
23143
"Okay..." - is displayed on the same line as the beeper noise.)
23144
23145
</div>
23146
23147
<!------------------->
23148
<div class=entry>
23149
23150
Can we make every kind of noun phrase production derive from a common
23151
NounPhraseProd base class?
23152
23153
</div>
23154
23155
<!------------------->
23156
<div class=entry>
23157
23158
Allow multiple actors per command line, tads2-style, as in "bob, go
23159
north. look. bill, go south."  (In tads 2, a new actor can be
23160
specified after a period.)  However, only allow this in "synchronous"
23161
mode, where the issuing actor waits for all commands to NPC's to
23162
complete before taking another turn; in asynchronous mode, do not
23163
allow mid-command target actor changes, because it's too confusing.
23164
23165
</div>
23166
23167
<!------------------->
23168
<div class=entry>
23169
23170
Fix problem in touchObj precondition: we assume that we can find a
23171
valid touch path, so we traverse the path without checking to see if
23172
we got a nil path.  In some cases (such as when the target object is
23173
in a location not sharing any common container with the actor), there
23174
is no touch path at all, so we need to deal properly with this
23175
possibility.
23176
23177
</div>
23178
23179
<!------------------->
23180
<div class=entry>
23181
23182
Fix visual command separation for 'undo' after a multi-command line,
23183
and for a multi-undo command line.
23184
23185
</div>
23186
23187
<!------------------->
23188
<div class=entry>
23189
23190
Modify/replace/delete grammar rules.  Add new syntax:
23191
23192
<p>
23193
<pre>
23194
  modify grammar production(tag): <new-grammar-rule>: 
23195
    <property-list> 
23196
  ;
23197
  replace grammar production(tag): <new-grammar-rule>: <class>
23198
    <property-list>
23199
  ;
23200
</pre>
23201
23202
<p>
23203
To make this workable, the "production(tag)" names of grammar match
23204
objects must be unique; change the compiler to enforce uniqueness of
23205
these names.
23206
23207
<p>
23208
Also, change VerbRule to include a tag: VerbRule(tag).  This will
23209
allow modify/replace to be used with VerbRule(tag) definitions to
23210
replace library verb grammar rules.
23211
23212
</div>
23213
23214
<!------------------->
23215
<div class=entry>
23216
23217
Add a mechanism for remapping a two-noun-phrase action to a different
23218
action after resolving first object.  For example, allow mapping
23219
ATTACK x WITH THROWING STAR to THROW THROWING STAR AT x.
23220
23221
<p>
23222
To do this, add a new pair of properties to TIAction: remapDobjProp
23223
and remapIobjProp; define these properties using the same template
23224
style as the rest of the properties in DefineTIAction.  Add a new
23225
remapTIAction() macro that can be used from within a remap() method
23226
to remap a command.
23227
23228
<p>
23229
Note that only the first-resolved object can be remapped, because the
23230
whole point is to effect the remapping before resolving the
23231
second-resolved object, so that the second-resolved object can be
23232
resolved using the rules of the new action rather than of the
23233
original action.
23234
23235
</div>
23236
23237
<!------------------->
23238
<div class=entry>
23239
23240
In BasicLocation.lookAround, remove the point-of-view object from
23241
the list of objects to be described, rather than removing the actor.
23242
23243
</div>
23244
23245
<!------------------->
23246
<div class=entry>
23247
23248
Move the grammar convenience macros (VerbRule, SingleDobj, etc) out
23249
of adv3.h and into us_eng.h - these are all specific to the English
23250
verb grammar, so they should be in the English-specific definitions
23251
rather than the language-independent definitions.
23252
23253
</div>
23254
23255
<!------------------->
23256
<div class=entry>
23257
23258
If a Daemon is created with an interval of zero or less, it'll put
23259
the scheduler into an infinite loop invoking the daemon, because the
23260
daemon will be permanently schedulable.  Force the interval to at
23261
least 1 on creation.
23262
23263
</div>
23264
23265
<!------------------->
23266
<div class=entry>
23267
23268
Add a lookAround() method to Thing, to generate a description from
23269
the point of view of the Thing.  This is necessary to allow things
23270
like remote cameras.  This method should call the container's
23271
lookAroundPov() method (which must also be added to Thing) with the
23272
point of view set self; this algorithm will eventually reach the
23273
innermost room-like object, which will display the appropriate
23274
room-like description.
23275
23276
</div>
23277
23278
<!------------------->
23279
<div class=entry>
23280
23281
Add a PAUSE command, to stop the real-time clock for games that
23282
use real-time events.
23283
23284
</div>
23285
23286
<!------------------->
23287
<div class=entry>
23288
23289
Add a grammar notation that specifies a match for one of several
23290
vocabulary properties.  With the '&lt;prod&gt;' grammar that was being
23291
kicked around for a while, the notation '<noun | adjective>' was
23292
appealing, but without the angle brackets, it's not obvious what the
23293
equivalent syntax would be.
23294
23295
<p>
23296
Use angle-bracket notation, even though we don't use it for
23297
individual tokens:  &lt;nounM nounN nounF&gt;
23298
23299
</div>
23300
23301
<!------------------->
23302
<div class=entry>
23303
23304
Add an explicit 'grammar' declaration with no matchable rules, so that
23305
production names can be declared without actually creating rules for
23306
them.
23307
23308
</div>
23309
23310
<!------------------->
23311
<div class=entry>
23312
23313
make 'inherited' after 'delegated' more consistent with the regular
23314
inheritance behavior (in particular, the relatively new dynamic
23315
inheritance search algorithm will fail to find a class related to
23316
'self' in the delegatee's superclass tree, so there will be nothing
23317
to inherit; ideally, we'd have an 'inheritance target' in the stack
23318
frame in addition to 'self')
23319
23320
</div>
23321
23322
<!------------------->
23323
<div class=entry>
23324
23325
NestedRoom.getTravelConnector refers to gActor.  The reason the method
23326
looks at gActor is that it wants to check if the actor can see the
23327
containing room, so that it can get the connector from the containing
23328
room.  Add an 'actor' parameter to getTravelConnector(), so that we
23329
can specify an actor explicitly and thus ask for travel connectors
23330
outside of turn execution contexts.
23331
23332
</div>
23333
23334
<!------------------->
23335
<div class=entry>
23336
23337
SouthwestAction is missing from action.t
23338
23339
</div>
23340
23341
<!------------------->
23342
<div class=entry>
23343
23344
noTravelIn, noTravelOut, noTravelDown - these need to override
23345
isConnectorApparent to return nil.
23346
23347
<p>
23348
Add redirectTravelIn, etc, which do show isConnectorApparent = true.
23349
23350
</div>
23351
23352
<!------------------->
23353
<div class=entry>
23354
23355
Add newActionObj alongside _newAction: the new function takes a
23356
pre-created action instance, rather than creating a new instance
23357
itself.
23358
23359
</div>
23360
23361
<!------------------->
23362
<div class=entry>
23363
23364
Add a getBestMatch() method to ResolvedTopic to retrieve the
23365
top-ranking object.  By default, provide an implementation that simply
23366
returns an arbitrary object from the strongest match list.  Games and
23367
library extensions could customize this to use a different topic
23368
picker mechanism as desired, but providing a decent default
23369
implementation would help authors get started without having to worry
23370
about coding their own topic framework if they didn't want anything
23371
specific here.  
23372
23373
</div>
23374
23375
<!------------------->
23376
<div class=entry>
23377
23378
Add a PreRestartObject, analogous to PreSaveObject, to allow any special
23379
actions to be performed before a restart.
23380
23381
</div>
23382
23383
<!------------------->
23384
<div class=entry>
23385
23386
execCommandTokens should probably switch the sense context upon
23387
discovering a target actor different from the issuing actor, before
23388
actually starting to execute the command.
23389
23390
</div>
23391
23392
<!------------------->
23393
<div class=entry>
23394
23395
Move all of the output management into discrete OutputStream objects.
23396
Associate filters, notifiers, capturers with individual streams.  By
23397
default, create one stream for the main text and another for the
23398
status line.
23399
23400
<p>
23401
<b>NOTE:</b> This change affects all of the notifier, filter, monitor, and
23402
capturer function interfaces.  All of these formerly global functions
23403
are now methods of the OutputStream class.
23404
23405
</div>
23406
23407
<!------------------->
23408
<div class=entry>
23409
23410
Regarding touch path calculation (see e.g. touchObj precondition):
23411
should we be finding a touch path to an object in a separate location
23412
not connected by containment, but connected by a SenseConnector?
23413
23414
</div>
23415
23416
<!------------------->
23417
<div class=entry>
23418
23419
Fix basicScoreChange reporting for changes of 1 (or -1) points: use
23420
singular "point".
23421
23422
</div>
23423
23424
<!------------------->
23425
<div class=entry>
23426
23427
change the T3 Workbench .tdc format to use .t3m files
23428
23429
</div>
23430
23431
<!------------------->
23432
<div class=entry>
23433
23434
vmrun: respond to Ctrl+Break to break into debugger
23435
23436
</div>
23437
23438
<!------------------->
23439
<div class=entry>
23440
23441
"parse-debug" command: accept the command without the "on" or "off"
23442
specifier, and simply invert the current mode.
23443
23444
</div>
23445
23446
<!------------------->
23447
<div class=entry>
23448
23449
Add a nounMultiList production alongside nounList.  Use this
23450
production in matching singleNoun, rather than using the regular
23451
nounList, so that we don't create spurious additional matches for the
23452
degenerate single noun phrase form of nounList.
23453
23454
</div>
23455
23456
<!------------------->
23457
<div class=entry>
23458
23459
For bags of holding, check (in Container.tryPuttingObjInBag) to make
23460
sure that the object being moved into the bag actually fits, and
23461
don't even try if it won't.  This will avoid spurious attempts and
23462
failures to move things in to a bag of holding implicitly after the
23463
bag becomes full.
23464
23465
</div>
23466
23467
<!------------------->
23468
<div class=entry>
23469
23470
Refactor the CommandProd-based productions in parser.t to move the
23471
methods into new classes, and base the defined grammars on the
23472
classes.  This will facilitate adding new commandPhrase grammar rules
23473
by allowing the existing behavior to be re-used via inheritance.
23474
23475
</div>
23476
23477
<!------------------->
23478
<div class=entry>
23479
23480
Add a new Actor property (revertTargetActorAtEndOfSentence) that, when
23481
set, tells the parser to consider target actor designations ("bob, go
23482
north...") in effect only until the end of a sentence.  When the
23483
property is set to true, switch the target actor back to the original
23484
issuing actor at the end of each sentence.
23485
23486
</div>
23487
23488
<!------------------->
23489
<div class=entry>
23490
23491
As a convenience, add a new StyleTag subclass, HtmlStyleTag, for tags
23492
with different renderings in HTML and plain text modes.  
23493
23494
</div>
23495
23496
<!------------------->
23497
<div class=entry>
23498
23499
Add some new style tags:
23500
23501
<ul>
23502
<li>&lt;.a&gt; - for &lt;a&gt; text (and use it for
23503
all links we generate)
23504
23505
<li>&lt;.statusroom&gt; - for the room name portion of
23506
the status line
23507
23508
<li>&lt;.statusscore&gt; - for the score/turn count
23509
portion of the status line
23510
</ul>
23511
23512
</div>
23513
23514
<!------------------->
23515
<div class=entry>
23516
23517
Add inputManager methods getKey() and getEvent() that provide covers
23518
for inputKey() and inputEvent(), respectively, the integrate with the
23519
real-time manager and the reports gatherer in the same manner as
23520
inputLine.
23521
23522
</div>
23523
23524
<!------------------->
23525
<div class=entry>
23526
23527
Don't use [badness] to reduce the priority of ordinal lists in
23528
disambiguation responses; instead, use the ranking mechanism to give
23529
ordinals a lower ranking than noun/adjective interpretations.
23530
23531
</div>
23532
23533
<!------------------->
23534
<div class=entry>
23535
23536
Fix looping problem with answering 'g' to disambiguation queries.
23537
(Don't store the response to a disambiguation query until after we
23538
actually know that the input is an answer to the query, as opposed to
23539
a new command.)
23540
23541
</div>
23542
23543
<!------------------->
23544
<div class=entry>
23545
23546
Do not notify sense path in moveInto() when traveling.  (Travel uses
23547
the separate TravelConnector mechanism, which doesn't necessarily map
23548
directly onto sense connections; we don't want to attempt to notify
23549
sense connections of travel because we don't actually use them for
23550
travel.)
23551
23552
</div>
23553
23554
<!------------------->
23555
<div class=entry>
23556
23557
When disambiguating interactively, if the response isn't in the full
23558
list, check to see if it's in the full scope list.  This allows for
23559
cases where the player really wants to try a command on something
23560
that we decide isn't logical - it's better to let the player try than
23561
to deny that the object is among the possible choices.
23562
23563
<p>
23564
We should test the scope list as a second pass rather than allowing
23565
the full scope on the first pass.  So, we should try first as we do
23566
now, limiting scope to the narrowed ("logical") list; then, if that
23567
fails, we should try again with the full scope list.
23568
23569
</div>
23570
23571
<!------------------->
23572
<div class=entry>
23573
23574
Add an equivalent of the tads 2 "->" syntax: this syntax allowed
23575
routing messages for one object to another object.  For example, if
23576
we wanted to route "open desk" to "open drawer", we would put "doOpen
23577
-> drawer" in the desk.  Define a new macro:
23578
23579
<p>
23580
<pre>
23581
  dobjForwardTo(Open, drawer)
23582
</pre>
23583
23584
<p>
23585
This is used <i>in place of</i> a dobjFor().
23586
23587
<p>
23588
(This was from Phil Lewis, who suggested "reroute" as the name and
23589
also suggested a slightly more general format: dobjReroute(drawer,
23590
Open).  It might also be useful to be able to specify the verb to
23591
forward separately, so that you could handle a verb with both a
23592
different verb and different target object, but the action is
23593
probably the same in most cases, so it seems more convenient to be
23594
able to omit it.)
23595
23596
</div>
23597
23598
<!------------------->
23599
<div class=entry>
23600
23601
In roomSmellLister (and roomListenLister), add a custom isListed
23602
method that checks a new property of the target object,
23603
isSmellListedInRoom (isSoundListedInRoom in the case of Noise
23604
objects).  Set these properties to true by default.  Add an isListed
23605
override to smellActionLister (and listenActionLister) that simply
23606
returns true.  This change allows an Odor/Noise to list in response
23607
to a >SMELL or >LISTEN without also showing in the normal room
23608
description, as it would by default.
23609
23610
</div>
23611
23612
<!------------------->
23613
<div class=entry>
23614
23615
Propagate the results of an action up to callers by returning the
23616
CommandReportList.  Actually, we'll have to return a list of
23617
CommandReportList objects, since one CommandReportList is generated
23618
per iteration for an iterated action.  The aggregate list could be
23619
stored in a CommandResults object, which could provide high-level
23620
analysis methods (e.g., isFailure()) to interpret the action results.
23621
23622
<p>
23623
To do this, return a CommandResults object describing the command
23624
reports list from newAction(), nestedAction(), and so on.
23625
23626
</div>
23627
23628
<!------------------->
23629
<div class=entry>
23630
23631
Provide a way of specifying a subclass of CommandReportList to use
23632
when executing a new or nested command.  To do this, callers use
23633
a new function that takes a particular CommandReportList subclass
23634
to use while calling a callback:
23635
23636
<p>
23637
<pre>
23638
  result = withCommandReportsClass(
23639
      MyCommandReportList, {: nestedActorAction(bob, SitOn, chair) });
23640
</pre>
23641
23642
</div>
23643
23644
<!------------------->
23645
<div class=entry>
23646
23647
In the tokenizer, if a word with a "'s" suffix explicitly appears in
23648
the dictionary with the "'s", do NOT make the "'s" into a separate
23649
token - keep the whole string with the "'s" as a single token.  This
23650
allows for cases where the grammar has a literal token with a "'s"
23651
suffix, and where vocabulary words (such as adjectives) are
23652
explicitly defined with "'s" suffixes.
23653
23654
</div>
23655
23656
<!------------------->
23657
<div class=entry>
23658
23659
In TravelConnector, allow for a single barrier rather than a list
23660
of barriers.  If the travelBarrier property is not a Collection of
23661
some kind, treat it as a single TravelBarrier.
23662
23663
</div>
23664
23665
<!------------------->
23666
<div class=entry>
23667
23668
Add a OneWayRoomConnector to make it easier to define a connector
23669
that connects one room to another but not vice versa.f
23670
23671
</div>
23672
23673
<!------------------->
23674
<div class=entry>
23675
23676
Add checkTravelConditions() to TravelConnector.  Call this from
23677
checkTravelBarriers().  By default, this does nothing; instances
23678
can override it to apply special conditions to the travel in lieu
23679
of creating a separate TravelBarrier object when the conditions
23680
don't need to be re-used in other connectors.
23681
23682
</div>
23683
23684
<!------------------->
23685
<div class=entry>
23686
23687
Fix indentation problem for grouped items in INVENTORY TALL lists.
23688
23689
</div>
23690
23691
<!------------------->
23692
<div class=entry>
23693
23694
Hide intangibles from 'all' by default.  Noises and odors should
23695
probably be included in 'all' for LISTEN/SMELL.
23696
23697
</div>
23698
23699
<!------------------->
23700
<div class=entry>
23701
23702
When trying to put objects into a bag of holding to make room to take
23703
a new object, don't even try moving an object that contains the bag
23704
of holding (because doing so will just fail with a message "the <bag
23705
of holding> is already in that").
23706
23707
</div>
23708
23709
<!------------------->
23710
<div class=entry>
23711
23712
Need a better way to say "the one in the room" than showing the room
23713
name, because that's not useful in input.  Should say something
23714
like "the match on the floor".
23715
23716
</div>
23717
23718
<!------------------->
23719
<div class=entry>
23720
23721
Once everything in a disambiguation list is a basic equivalent, we
23722
could use the 'name' of the objects to display the prompt, rather
23723
than using the input text.
23724
23725
</div>
23726
23727
<!------------------->
23728
<div class=entry>
23729
23730
In Thing.initializeEquivalent, deal with the possibility that we have
23731
a base class with a separate equivalent grouper.  Create a separate
23732
grouper for the subclass by testing to see if equivalentGrouper is
23733
defined <i>directly</i> by the class object.  If there is an inherited
23734
grouper, we must create our own separate grouper for the subclass,
23735
AND we must take the superclass grouper out of the listWith for the
23736
subclass (since it will inherit the base class listWith by default).
23737
23738
</div>
23739
23740
<!------------------->
23741
<div class=entry>
23742
23743
In action.t around line 1532, when we're adding the UnclearDisambig
23744
flag, we might want to suppress the flag if the object we selected
23745
and the objects we rejected are basic equivalents of one another.
23746
This avoids weird situations such as
23747
23748
<p>
23749
<pre>
23750
  >light match
23751
  (the match)
23752
</pre>
23753
23754
<p>
23755
when we have one match we're holding and another in the matchbook:
23756
we choose the one we're holding over the one in the matchbook because
23757
of the must-be-holding precondition to lighting a match, but mentioning
23758
which one we're choosing is weird because it doesn't tell us anything.
23759
23760
</div>
23761
23762
<!------------------->
23763
<div class=entry>
23764
23765
<pre>
23766
>drop match
23767
Which match, one of your matches, or the match in the matchbook?
23768
23769
>my match
23770
Which match, one of your matches, or the match in the matchbook?
23771
</pre>
23772
23773
<p>
23774
...etc.  The problem is that we're taking "my match" to mean any
23775
match in my possession for parsing purposes, whereas we differentiate
23776
holding from indirectly owned.  Ideally, we'd prefer to treat "my
23777
match" as "the match I'm holding directly" when it's ambiguous.
23778
23779
</div>
23780
23781
<!------------------->
23782
<div class=entry>
23783
23784
Add a disambigName property, and use it instead of the ordinary name
23785
when generating disambiguation prompts.  (We'll need aDisambigName,
23786
theDisambigName, and countDisambigName as well to round out the set.)
23787
23788
</div>
23789
23790
<!------------------->
23791
<div class=entry>
23792
23793
Add "x in y" grammar.
23794
23795
</div>
23796
23797
<!------------------->
23798
<div class=entry>
23799
23800
Add a mechanism for distinguishing equivalents with different states:
23801
23802
<p>
23803
<pre>
23804
  Which candle to you mean, the lit candle or the unlit candle?
23805
23806
  -but not-
23807
  Which wax do you mean, the unlit candle or the seal?
23808
  -which should just be
23809
  Which wax do you mean, the candle or the seal?
23810
</pre>
23811
23812
<p>
23813
Use this mechanism to create a base class for light sources.  We
23814
can use this for things like matches and candles.  The disambig
23815
name for an object is "lit x" or "unlit x", so we add the adjective
23816
"lit" or "unlit" according to state.  Check the adjective in parseName.
23817
23818
<p>
23819
Use this same mechanism to specify by owner when owner is a
23820
distinguishing factor - "which gas mask do you mean, yours, or
23821
teeterwaller's?"
23822
23823
<p>
23824
To do this, associate with each object a list of "distinguisher"
23825
objects.  A candle might include the "lit" distinguisher object, and
23826
probably all objects would include the "owner" distinguisher.  We'd
23827
make a list of all of the distinguishables in common to the set of
23828
equivalents, then run through the common set.  For each one, we'd ask
23829
the distinguisher if the list of equivalents we have is
23830
distinguishable via this distinguisher.  The "lit" distinguisher
23831
would return true if the objects were all in different "lit" states,
23832
and the "owner" distinguisher would return true if all had different
23833
owners.  We'd stop at the first distinguisher that can tell all of
23834
the objects apart.  The distinguisher would give us the method to
23835
call in each of the objects to list its distinguishing name - the
23836
"lit" distinguisher would call the litName property, for example,
23837
which would display "the lit candle" or "the unlit candle"; the
23838
"owner" distinguisher would display "yours" or "teeterwaller's".
23839
23840
<p>
23841
The response would have to be handled by the normal disambiguation
23842
response mechanism, so the objects would have to conspire with the
23843
distinguisher to have the proper adjectives.  This is easy, though,
23844
because the objects are the ones displaying the adjectives in the
23845
first place when they show the disambiguation list.
23846
23847
<p>
23848
If we find no distinguisher that can tell all of the items apart,
23849
we'd look for one that can tell at least some of the items apart, and
23850
phrase it like this: "the lit candle, or one of the unlit candles".
23851
If they select one of the ones indistinguishable with this
23852
distinguisher, we'd iterate, and maybe pick it up with a separate
23853
distinguisher next time.
23854
23855
<p>
23856
If none of the distinguishers can tell any of the objects apart, we'd
23857
simply choose one arbitrarily like we do now.
23858
23859
<p>
23860
<pre>
23861
>take candle
23862
Which candle do you mean, the lit candle, or one of the unlit candles?
23863
23864
>unlit
23865
Which do you mean, your candle, or one of Bob's?
23866
23867
>bob's
23868
(arbitrarily picking one of bob's several unlit candles)
23869
Taken.
23870
</pre>
23871
23872
<p>
23873
Note that for ownership distinctions, need to offer a way to refer to
23874
unowned objects:
23875
23876
<p>
23877
<pre>
23878
>get candle
23879
Which candle do you mean, Bob's, or the other one?
23880
<i>-or-</i> Which candle do you mean, Bob's, or another one?
23881
23882
<i>[responses would include...]</i>
23883
>another / another one / another gold coin / one of the others 
23884
 / one of the other gold coins / other / the other / the other one
23885
 / the other gold coin / other gold coin
23886
</pre>
23887
23888
</div>
23889
23890
<!------------------->
23891
<div class=entry>
23892
23893
Hide actors from 'all' for all verbs by default.
23894
23895
</div>
23896
23897
<!------------------->
23898
<div class=entry>
23899
23900
For "put in" and "put on", use roughly the same strategy as "take"
23901
for generating the "all" list: include only objects that are directly
23902
in the actor's location, or in fixed objects in the actor's location,
23903
as "take" does, but also include objects that the actor is directly
23904
holding.  Keep the same iobj/in-iobj exclusions.
23905
23906
</div>
23907
23908
<!------------------->
23909
<div class=entry>
23910
23911
Break up TravelConnector.checkTravelConditions() into two separate
23912
methods (canTravelerPass(traveler) and explainTravelBarrier(traveler)),
23913
just like TravelBarrier.
23914
23915
</div>
23916
23917
<!------------------->
23918
<div class=entry>
23919
23920
Fix Thing.normalizePath() so that it makes two separate passes over
23921
the list.  It should apply the PathThrough tranformation first, then
23922
the PathPeer transformation as a second pass.  (Performing both
23923
transformations both on a single pass can cause PathThrough
23924
transformations to be missed, because the PathPeer changes the list in
23925
such a way that the PathThrough transformation doesn't recognize a
23926
needed change.  The PathThrough condition could alternatively be
23927
modified to recognize PathPeer operations, but it's easier to do
23928
things in two passes.  Note that doing PathThrough first is safe,
23929
because it only adds to the list - it never drops any operations that
23930
the PathPeer transformation looks at.)
23931
23932
</div>
23933
23934
<!------------------->
23935
<div class=entry>
23936
23937
Add distance differentiation for 'examine' descriptions (and for
23938
'listen') and 'smell' descriptions as well).  Specifically, add
23939
distantDesc and obscuredDesc, and call them from basicExamine
23940
according to the current point of view.  Add corresponding methods for
23941
'listen' and 'smell' descriptions.
23942
23943
</div>
23944
23945
<!------------------->
23946
<div class=entry>
23947
23948
Add automatic state listing to the equivalent grouper.  Use a new
23949
Thing method, getState, that returns a ThingState object.  Use this
23950
object to group equivalents by state and to show the state of each
23951
item.
23952
23953
</div>
23954
23955
<!------------------->
23956
<div class=entry>
23957
23958
Use the ThingState object to provide the ordinary status description
23959
of an object.
23960
23961
</div>
23962
23963
<!------------------->
23964
<div class=entry>
23965
23966
Use ThingState to provide automatic matchName() filtering by state.
23967
Add a property to ThingState, stateTokens, that lists tokens that
23968
can only be used in noun phrases referring to an object in the state.
23969
23970
</div>
23971
23972
<!------------------->
23973
<div class=entry>
23974
23975
Integrate Steve's exit lister package into the library.
23976
23977
</div>
23978
23979
<!------------------->
23980
<div class=entry>
23981
23982
It would be nice to have a sorting order for the directions, so we
23983
list in a more canonical order: north, south, east, west, northeast,
23984
northwest, southeast, southwest, up, down, in, out.
23985
23986
</div>
23987
23988
<!------------------->
23989
<div class=entry>
23990
23991
When two exits have the same destination, list them together: "south
23992
(or out) to the front yard".
23993
23994
</div>
23995
23996
<!------------------->
23997
<div class=entry>
23998
23999
Don't show exits to dark rooms in the dark.
24000
24001
</div>
24002
24003
<!------------------->
24004
<div class=entry>
24005
24006
In listing exits from a dark room, maybe we should show exits leading
24007
to rooms with light, since travel would be allowed to those locations.
24008
24009
</div>
24010
24011
<!------------------->
24012
<div class=entry>
24013
24014
Change the way we figure out if travel from a dark room to an
24015
adjoining lit room is possible.  Add a separate TravelConnector
24016
method that specifically determines if the connector itself is
24017
visible to a given actor in a given origin location when the origin
24018
location is dark.  By default, make a connector visible from a dark
24019
location when the destination room is lit.  This will provide the
24020
customary behavior (i.e., dark-to-dark travel is prohibited, but
24021
dark-to-light is allowed on the theory that some of the light from
24022
the destination leaks through to the origin, making the connection
24023
itself self-illuminating and thus visible even in the dark origin
24024
room), while more clearly articulating the rule by making the
24025
visibility of the connector the explicit factor in determining
24026
whether or not the travel is allowed, and also providing a clean way
24027
to override the default heuristic for visibility of the connector for
24028
particular connections that should use a different rule.
24029
24030
</div>
24031
24032
<!------------------->
24033
<div class=entry>
24034
24035
Add an option to show available exits in the status line (using
24036
a terse display that just lists the direction names).
24037
24038
</div>
24039
24040
<!------------------->
24041
<div class=entry>
24042
24043
Make Surface.PutOn behave like Container.PutIn with respect resolving
24044
the indirect object using the tentative direct object list: if
24045
everything in the tentative direct object match list is already on
24046
the indirect object, flag the indirect object as illogical.
24047
24048
</div>
24049
24050
<!------------------->
24051
<div class=entry>
24052
24053
Sense Event Model:  Create a new class, SensoryEvent, that can be used
24054
to trigger transient sensory events that actively notify interested
24055
observers of their occurrence.
24056
24057
</div>
24058
24059
<!------------------->
24060
<div class=entry>
24061
24062
Add convenience macros for remapTIAction that define the full remapping
24063
for a dobj or iobj to another action, with the same or reversed noun
24064
phrase order:
24065
24066
<p>
24067
<pre>
24068
  dobjRemapTI(OpenWith, UnlockWith)
24069
  dobjRemapTIReverse(FillWith, PutIn)
24070
  dobjRemapTIReverse(ThrowAt, AttackWith)
24071
</pre>
24072
24073
</div>
24074
24075
<!------------------->
24076
<div class=entry>
24077
24078
examineSpecialContents should probably differentiate according to POV
24079
and sight viewing conditions.
24080
24081
</div>
24082
24083
<!------------------->
24084
<div class=entry>
24085
24086
Change CommandReportList to a SimpleOutputCapturer.  We don't actually
24087
want to process any notifiers or monitors when capturing report results,
24088
because we turn them into a report list that can be reordered.  We want
24089
to wait until we actually display the reports to notify anything of the
24090
output.
24091
24092
</div>
24093
24094
<!------------------->
24095
<div class=entry>
24096
24097
<pre>
24098
>i
24099
You are carrying three matches (one lit), and a matchbook (which
24100
contains two matches).
24101
24102
>x match
24103
Which match do you mean, an unlit match, or the lit match?
24104
24105
>an unlit match
24106
(the match)
24107
The match is an ordinary match.
24108
</pre>
24109
24110
<p>
24111
It would be better not to make an arbitrary choice here, unless they
24112
explicitly said "any unlit match".  We should have another go at
24113
asking for detail in this case.
24114
24115
</div>
24116
24117
<!------------------->
24118
<div class=entry>
24119
24120
Add TITLEs to &lt;A HREF&gt;'s in system messages.
24121
24122
</div>
24123
24124
<!------------------->
24125
<div class=entry>
24126
24127
Exit lister: if we have multiple exits from a location with nil
24128
destination names, we are incorrectly grouping them as though they
24129
had the same destination name.  The result is that we only see one
24130
such exit in an EXITS list.  Destinations with nil destination names
24131
should be treated as unknown destinations.
24132
24133
</div>
24134
24135
<!------------------->
24136
<div class=entry>
24137
24138
Sort adv3.tl alphabetically (except for 'modify' order dependencies).
24139
24140
</div>
24141
24142
<!------------------->
24143
<div class=entry>
24144
24145
Add Dan Schmidt's hyphen-converting output filter to output.c
24146
24147
</div>
24148
24149
<!------------------->
24150
<div class=entry>
24151
24152
Add Dan's Thing.canBeSeenBy, Thing.canBeSeen, etc.  (These are
24153
convenience methods, especially for canBeSeen and its like, which
24154
operate on the player character, saving a little typing by making
24155
'gPlayerChar' implicit.)
24156
24157
</div>
24158
24159
<!------------------->
24160
<div class=entry>
24161
24162
Add Dan's Event.delayEvent, removeEvent methods
24163
24164
</div>
24165
24166
<!------------------->
24167
<div class=entry>
24168
24169
Add an event manager method that cancels an event based on the
24170
obj/prop combination, to save work for cases where this uniquely
24171
identifies the event (this way, the author doesn't have to go to the
24172
extra trouble of saving the Event object reference if the event can
24173
be uniquely identified without it).
24174
24175
</div>
24176
24177
<!------------------->
24178
<div class=entry>
24179
24180
Add a "mass" or "collective" noun property, for objects that refer to
24181
collections of large numbers of smaller parts, or continuously-measured
24182
quantities: "some popcorn", "some water".  (Is there anything that this
24183
changes besides changing aName to "some <name>"?  Should think about it.)
24184
24185
</div>
24186
24187
<!------------------->
24188
<div class=entry>
24189
24190
Add a lower-level base class for Switch, OnOffControl, that keeps
24191
track of the on/off state and accepts "turn on" and "turn off".
24192
Define the additional switch-specific verbs ("switch" and "flip")
24193
only in the Switch subclass - this allows for adding on/off behavior
24194
without making something look exactly like a light switch.
24195
24196
</div>
24197
24198
<!------------------->
24199
<div class=entry>
24200
24201
Add a GO BACK command to return to the most recent location (if the
24202
connector in was reversible).
24203
24204
</div>
24205
24206
<!------------------->
24207
<div class=entry>
24208
24209
Keep track of the last "interlocutor" for each actor; this is actor
24210
last addressed in a targeted command ("bob, go north"), or the last
24211
actor in a conversational command - ASK ABOUT, TELL ABOUT, SHOW TO,
24212
GIVE TO.  For the conversational commands, if the actor is left out
24213
(ASK ABOUT GOLD, TELL ABOUT STORM), use the performing actor's most
24214
recent interlocutor as the default, if the interlocutor is still
24215
within talking range.
24216
24217
</div>
24218
24219
<!------------------->
24220
<div class=entry>
24221
24222
Create a subclass of Actor, UntakeableActor, for an actor that can't
24223
be taken or moved.  Define an additional subclass, Person, to
24224
represent human characters, and provide some custom "fixed" messages
24225
for it.
24226
24227
</div>
24228
24229
<!------------------->
24230
<div class=entry>
24231
24232
Ensure that the SCORE and FOOTNOTE modules are completely modular,
24233
so that they can simply be omitted from the build if not required.
24234
24235
</div>
24236
24237
<!------------------->
24238
<div class=entry>
24239
24240
Get rid of libMessages.openBracket and closeBracket; instead, add
24241
a style tag, <.parser>...<./parser>.
24242
24243
Also, add <.notification>...<./notification> for notifications
24244
(score changes, FOOTNOTE instructions, etc.).
24245
24246
</div>
24247
24248
<!------------------->
24249
<div class=entry>
24250
24251
Change withBrackets() to parserMessage(), for better documentary
24252
effect.
24253
24254
</div>
24255
24256
<!------------------->
24257
<div class=entry>
24258
24259
Simplify the menagerie of output filters, notifiers, monitors,
24260
and capturers, reducing everything to a single type (filter).
24261
Enforce stacking of filters.
24262
24263
</div>
24264
24265
<!------------------->
24266
<div class=entry>
24267
24268
Get rid of the paragraph suppression immediately following input.
24269
Instead, use the command sequencer to display the appropriate kind
24270
of separation.
24271
24272
</div>
24273
24274
<!------------------->
24275
<div class=entry>
24276
24277
Rename CommandReportList to CommandTranscript, and rename
24278
gCommandReports to gTranscript.
24279
24280
</div>
24281
24282
<!------------------->
24283
<div class=entry>
24284
24285
Add resolved object arguments to Actor.addPendingAction,
24286
Actor.addFirstPendingAction.
24287
24288
</div>
24289
24290
<!------------------->
24291
<div class=entry>
24292
24293
Rearrange arguments to Actor methods addPendingCommand,
24294
addPendingAction, addFirstPendingCommand, addFirstPendingAction to
24295
move the firstInSentence flag first.  This will keep everything
24296
consistent with the rearrangement necessitated by adding the varargs
24297
resolved object list to addPendingAction and addFirstPendingAction.
24298
24299
</div>
24300
24301
<!------------------->
24302
<div class=entry>
24303
24304
When a command is applied to several objects, and processing the
24305
command for some of the objects involves implied subcommands, set
24306
off the results for the objects with implied subcommands visually,
24307
by putting an extra paragraph break before and after each result
24308
for an object with implied subcommands:
24309
24310
<p>
24311
<pre>
24312
PO Box: Taken.
24313
red ball: Taken.
24314
24315
iron key:
24316
(First putting the red ball in the duffel bag to make room)
24317
Taken.
24318
24319
blue test booklet: Taken.
24320
24321
brass key:
24322
(First putting the red book in the duffel bag to make room)
24323
Taken.
24324
24325
gold coin: Taken.
24326
gold coin: Taken.
24327
</pre>
24328
24329
</div>
24330
24331
<!------------------->
24332
<div class=entry>
24333
24334
Use a new style tag, <.commandsep>, for command separation,
24335
eliminating the method call commandSequencer.startNewCommand().
24336
Using a tag instead of a method call will work better with text that
24337
doesn't reach the output stream immediately (for example, text that
24338
is queued into a command transcript during command results display).
24339
24340
</div>
24341
24342
<!------------------->
24343
<div class=entry>
24344
24345
In Thing.construct(), initialize the new object's vocabulary words and
24346
add them to the global dictionary.
24347
24348
</div>
24349
24350
<!------------------->
24351
<div class=entry>
24352
24353
Add information on the connector back, if known, to the EXITS display:
24354
24355
<p>
24356
<pre>
24357
  Obvious exits lead north, back to the east, and south to the den.
24358
  ...north; east, back to the living room; and south, to the den.
24359
</pre>
24360
24361
</div>
24362
24363
<!------------------->
24364
<div class=entry>
24365
24366
For NPC's, the announcement/result format for implied commands should
24367
probably be changed.  In particular, we should probably just treat NPC
24368
implied actions as full separate commands:
24369
24370
<p>
24371
<pre>
24372
>bob, north
24373
Bob opens the door.
24374
24375
Bob departs through the door.
24376
</pre>
24377
24378
</div>
24379
24380
<!------------------->
24381
<div class=entry>
24382
24383
For NPC's, don't allow interactive defaulting for an implied command.
24384
24385
</div>
24386
24387
<!------------------->
24388
<div class=entry>
24389
24390
For NPC's, if an implied command fails, we should fail with an indication
24391
that the NPC needs to perform the implied command:
24392
24393
<p>
24394
<pre>
24395
>bob s
24396
Bob must open the door before he can do that.
24397
24398
>bob, open door
24399
Bob must unlock the door before he can do that.
24400
</pre>
24401
24402
</div>
24403
24404
<!------------------->
24405
<div class=entry>
24406
24407
Get rid of gCommandReportClass and withCommandReportsClass.  Instead,
24408
add a parameter to _newAction() to specify the transcript class to
24409
use.
24410
24411
</div>
24412
24413
<!------------------->
24414
<div class=entry>
24415
24416
Add a new BasicLocation method, getRoomPartLocation(part), which
24417
returns the immediate container of the given room part, as perceived
24418
in that location.  Top-level rooms would generally just return 'self'
24419
if they have the room part, nil if not.  Nested rooms would generally
24420
pass this up to their containers, because they don't have room parts
24421
themselves in most cases.  Nested rooms with their own room parts
24422
would handle it themselves.
24423
24424
</div>
24425
24426
<!------------------->
24427
<div class=entry>
24428
24429
"x floor" - should list objects that are on the floor; likewise for
24430
other room parts (walls, ceiling).  Use a separate listing test
24431
(isListedInRoomPart(part)) to allow objects to opt out of being
24432
listed specifically in such cases.
24433
24434
<p>
24435
For special descriptions, add a "room part location" property - this
24436
is a purely advisory property used only for finding contents of the
24437
floor and so on.  When we "x floor", show special descriptions only
24438
for objects whose roomPartLocation is the floor of interest.
24439
24440
</div>
24441
24442
<!------------------->
24443
<div class=entry>
24444
24445
Re-enable the transcript after prompting for interactive resolution
24446
(reading an OOPS response, a disambiguation response, etc).
24447
24448
</div>
24449
24450
<!------------------->
24451
<div class=entry>
24452
24453
Add a method to Action to swap the roles of the tentative objects,
24454
for use with the 'verify' forwarding for TIAction remapping.  Add a
24455
call to this method to the dobjRemapTIReverse/iobjRemapTIReverse
24456
macros before they forward their 'verify' calls.
24457
24458
</div>
24459
24460
<!------------------->
24461
<div class=entry>
24462
24463
When an action is remapped, and we need to announce an object (such
24464
as a defaulted object), announce the <i>entire</i> action, not just the
24465
object.  For example:
24466
24467
<p>
24468
<pre>
24469
>fill bucket
24470
(dipping the bucket into the river)
24471
24472
>fill bucket
24473
(pouring the coffee into the bucket)
24474
</pre>
24475
24476
<p>
24477
This is important because the normal announcements are worded with the
24478
intention of being tacked onto the end of what the player typed; when
24479
the action is remapped, the action we're actually executing is different
24480
from what the player typed, so phrase fragments that are intended to be
24481
added to what the player typed are no long applicable.
24482
24483
</div>
24484
24485
</body>
24486
</html>