1 The Inform Standard Library
2 ===========================
4 The standard header files are stored in lower-case here. Symbolic links
5 to other semi-standard names get created upon installation (e.g.
6 verblib.h gets symlinked to Verblib.h and VerbLib.h) -- except on
7 Cygwin, where case doesn't seem to matter.
9 Version 6.12.1 (7 June 2016)
10 ============================
12 This is a maintenance release focusing entirely on bug fixes. No new
13 features have been added.
18 * TAKE ROCKS, TAKE ALL, TAKE ROCKS mistakenly tried to take things from
19 an NPC if one was in the room.
21 * DM4 Exercise 32 failure corrected. Also fixed a problem that caused
22 Glulx to get stuck in a loop.
24 * L__M(##Give, 2) wasn't correctly parameterized for voices and tenses.
26 * Improved some nonsensical responses to DROP.
28 * Corrected ordering NPC to take and drop multiple objects.
30 * Corrected problems with DropSub and ImplicitTake.
32 * Faulty OOPS correction partially fixed.
35 Version 6.12.0 (19 December 2015)
36 =================================
38 This release of the Inform Library marks the first release after custody
39 was taken over by David Griffith. It is now housed at
40 https://github.com/DavidGriffith/inform6lib. This release focuses
41 on bugs reported at http://www.inform-fiction.org/patches/library.html.
42 A few significant enhancements have been added as well, mainly having to
43 do with an abortive effort to produce Inform 6.40. An old repository of
44 that can be found at https://github.com/DavidGriffith/inform-2006.
50 First-person and third-person narrative voices are natively supported.
52 Default mode is now VERBOSE.
54 Added infglk.h for more convenient programming for the Glulx virtual
57 There is now a Global "no_infer_message" which can be used in the
58 ChooseObjects() routine to suppress an inference message for
59 particular match. This global is reset to false after the turn is
62 There is now a Global "no_implicit_actions" which can be used to tell
63 the library not attempt to do things that implicitly must be done. For
64 example, the PC is holding a sack containing an apple and the command
65 "DROP APPLE" is typed. With no_implicit_actions set to true, the
66 Library will complain instead of taking the apple out of the sack before
67 dropping it. Once this global is set, it stays set.
69 If you add "Constant NO_INITIAL_LOOK;" to the beginning of your code,
70 the library will not do an initial LOOK at the beginning of your
73 There is now an optional Epilogue() function. This will execute when
76 TAKE ALL has been modified such that scenery or animate objects will not
77 be taken. To revert back to traditional behavior, add "Constant
78 TRADITIONAL_TAKE_ALL;" at the beginning of your program.
80 If you want to use color in your game, you must add "Constant COLOUR;"
81 or "Constant COLOR;" to the beginnning of your code. This was required
84 To deal with L61126, a new global has been introduced
85 parser_inflection_func. Whenever parser_inflection is set as a
86 function, parser_inflection_func must be set to true. When the parser
87 is done with it, parser_inflection_func is set back to false. Under the
88 Z-machine, it is possible to tell if a global is a common property or a
89 function. This is not so with the Glulx VM. This change goes for both
90 Z-machine and Glulx. For background on how one might use
91 parser_inflection, see Section 35 of the DM4.
97 Items of the form "Issue L61036" quote the bug’s reference number in the
98 'Library' section of the Inform Patch List at
99 http://inform-fiction.org/patches/library.html
101 * WAVE AT has been improved.
103 * Handling of ambiguous orders given to NPCs has been improved.
105 * Fixed a problem with misparsing caused by incomplete orders.
108 each_turn property causes runtime error.
109 Problem: An each_turn property with both a local routine and a routine
110 inherited from a Class causes a runtime error in Strict mode.
114 GET IN now matches Compass object.
115 Adding "in_obj.&name-->0 = '.ignore';" to Initialise() reverts back to
116 the previous behavior.
120 "statusline time;" statement isn't recognized.
121 Problem: When I compile Greystone with 6.30 and 6/11 my statusline time;
122 statement is seemingly ignored; the game runs by moves and not a clock.
123 If I revert back to 6.21 and 6/10 the statusline is indeed a clock again
124 and not a move counter.
125 Status: Unable to reprodu
128 ListMaker doesn't support 'serial' commas.
129 Problem: The WriteListFrom() listmaker doesn't support 'serial' commas
130 (aka Oxford or Harvard commas): Tom, Dick, and Harry.
134 'Game uses colour' bit is always set.
135 Problem: Every game compiled with the 6/11 library has the 'game uses
136 colour' bit set in the Flags2 header word.
137 Fixed: From now on, if you want a game to use color, add "Constant
138 COLOUR;" or "Constant COLOR;" to the beginning of your code.
142 Improvement to LibraryExtensions.RunUntil.
143 Problem: The LibraryExtensions.RunUntil property (new at 6/11 and not
144 currently used by the library) should return simply true or false if it
149 (The) with 'proper' should capitalise object name.
150 Problem: In the case of an object with the 'proper' attribute and a
151 lower-case name (such as "your nose", "your corduroy trousers", "your
152 mother's purse"), the (The) print rule should capitalise the first
153 letter of the object name, so that library messages such as (The) x1,
154 " ", (isorare) x1, " empty." correctly produce "Your mother's purse is
159 indef_mode not restored.
160 Problem: When printing an object with the proper attribute, the
161 functions IndefArt() and CIndefArt() temporarily modify -- but do not
162 restore -- the value of the global variable indef_mode.
166 Problem with 'Give reverse' grammar.
170 Inference message inconsistency.
171 Problem: In a pile of several indistinguishable objects, taking them
172 from the floor does not generate an (inference) message, but it does
173 when the final one is taken. (See also Suggestion 48)
177 Multiple AGAINs treated as one.
181 WITHOUT_DIRECTIONS causes compilation error.
182 Problem: Version 6/11 of the Inform Library fails to compile if the
183 constant WITHOUT_DIRECTIONS is set and the objects 'u_obj' and 'd_obj'
184 aren't defined, because a few library routines expect those objects to
189 Size of upper window not restored properly on UNDO.
190 Problem: Compile and run a trivial game with Nitfol. When the game
191 begins, type WAIT and then UNDO. Nitfol displays the message [ERROR:
192 output]: illegal line for set_cursor (1) 46968 (1,1) This happens in
193 DrawStatusLine() and the reason is that the upper window has height 0,
194 but the Library tries to position the cursor at (1,1).
195 Comment: I couldn't get Nitfol to complain like this, but applied the
199 Numbers in the name property.
200 Problem: Code such as this would cause "GET 1" to not match the box
201 Object -> box1 "box marked 1"
202 with name 'box' 'marked' '1//',
203 description "It's a wooden box marked with the number 1.";
204 Object -> box2 "box marked 2"
205 with name 'box' 'marked' '2//',
206 description "It's a wooden box marked with the number 2.";
210 'multiheld' can match unholdable objects.
211 Problem: Contrary to the DM4, multiheld sometimes matches objects that
212 are not held. This would be OK if the objects were then implicitly
213 taken, like they are for held, but they are not.
217 Poor response from WAVE SELF.
218 Problem: The message produced by WAVE SELF -- "But you aren't holding
219 you" -- makes little sense.
223 Problem with <action> statements in Infix.
227 'thedark.initial' is never called.
228 Problem: The library thoughtfully provides thedark.initial, but it is
229 never called unless you are diabolical enough to make thedark contained
230 by some location, which I'm sure is not what it was meant for. The DM is
231 a bit contradictory about the purpose of thedark.initial, but the
232 functionality that makes the most sense is that it is called at the
233 transition from lighted to darkened. This makes up a gap in
234 functionality: NewRoom() is called on light-to-light and dark-to-light;
235 DarkToDark() is called on dark-to-dark, but absolutely nothing is called
240 TRACE should distinguish matched and inferred token.
241 Problem: When the parser partially matches a phrase, the TRACE command
242 should not say "token resulted in success" for terms that it did not
243 match but sucessfully inferred; instead it should state that those
244 terms were inferred. This would avoid the phrase "token resulted in
245 success" phrase meaning two different things -- actually matching and
247 Status: Won't fix. Maybe will fix in 6/13.
250 Preposition parsing is too simplistic.
251 Status: Fixed (by way of L61127)
254 add_to_scope of parentless object causes error.
255 Problem: Consider an object which has no parent, and is brought into
256 scope by an add_to_scope property. An attempt to take that object causes
258 [** Programming error: tried to test "has" or "hasnt" of nothing **]
259 [** Programming error: tried to test "has" or "hasnt" of nothing **]
260 That's hardly portable.
264 Conflict between 'describe' and 'initial' properties.
265 Problem: This object displays its 'initial' message even though it has
266 'moved' attribute; this is because of the presence of the 'describe'
267 property, even though it returns false.
271 Minor problem with parse_name.
272 Problem: A (rather minor) error with the parse_name routine. On page
273 209, the DM4 states: ...
277 Spurious space with 'articles' property.
278 Problem: The rarely-used articles property defines an array of strings.
279 (The property is provided for non-English languages where irregular
280 nouns may have unusual vowel-contraction rules with articles.) The DM4
281 gives an example appropriate for a French game, with three strings in
284 with name 'haricot' 'legume',
285 articles "Le " "le " "un ",
287 Note that each string includes its individual trailing space, if
288 appropriate. This is important, because a definite article like l' must
289 be followed immediately by the object's name, without any intervening
290 space. However, in fact a space does appear.
294 match_list and match_scores over-run.
295 Problem: The problem is that match_list-->number_matched is being
296 accessed, when match_list has length only number_matched (that is,
297 entries 0..number_matched-1). In particular this causes errors when th
298 match_list is of full length (64 entries). Similarly for match_scores.
302 parser_inflection requires common properties in Glulx.
303 Problem: Glulx cannot distinguish between a global that is a function or
304 a common property. They must be addressed differently. Code has been
305 introduced to require the author to explicity declare if
306 parser_inflection is a function or a common property.
310 Improve multiexcept look-ahead.
311 Problem: When the parser processes a grammar line that uses multiexcept
312 or multiinside, it jumps ahead to match the second noun in order to
313 provide context for the first one. However, in doing so, it skips over
314 all the prepositions in the input, without caring whether they match the
315 prepositions in the grammar line. If the second noun is ambiguous, this
316 means the player may be asked a disambiguation question for a grammar
317 line that has no chance of succeeding, whereas the grammar line that
318 eventually succeeds might not even need disambiguation (thanks to
319 different token type or ChooseObjects).
320 This also fixes L61120
322 I have also applied a fix submitted by Nathan Schwartzman at
323 http://inform7.com/mantis/view.php?id=636.
326 OOPS sometimes changes wrong word.
327 Problem: The OOPS command doesn't necessarily change the faulty word. In
328 the examples below, 'ZZZ' should be corrected to 'RUBY'. This happens in
329 the first example, but not the second.
333 Results from 'grammar' property are misplaced.
334 Problem: An animate or talkable object's grammar property can return 1
335 to mean (quoting from DM4) "you can stop parsing now because I have done
336 it all, and put the resulting order into the variables action, noun and
337 second". However, the library code to handle this return value does not
342 Version 6/11 (27 February 2004)
343 ===============================
348 * The library automatically defines four constants: LIBRARY_PARSER at
349 the end of Parser.h, LIBRARY_VERBLIB at the end of VerbLib.h,
350 LIBRARY_GRAMMAR at the end of Grammar.h, and LIBRARY_ENGLISH at the
351 end of English.h. Contributed library extensions can use these constants to
352 check that they have been Included in the correct location. A fifth
353 constant LIBRARY_VERSION, currently defined as the number 611, can be
354 checked by extensions which require this particular version of the
357 * The word "wall" has been removed from the CompassDirection objects
358 defined in English.h, whose names are now simply "north", "south", etc.
360 * The verbs LOOK [TO THE] NORTH, LOOK DOWN, LOOK OUT[SIDE] etc -- but
361 not LOOK IN[SIDE], which is already available -- have been added. By
362 default, the response is of the form "You see nothing unexpected...",
363 but you can change this for individual directions in individual rooms
364 by providing a compass_look property
366 Room study "Your study"
367 with description "There is a doorway to the east of this austere room.",
369 if (obj == e_obj) "You see a doorway.";
370 if (obj == n_obj or s_obj or w_obj) "You see the wall.";
374 This enhancement uses the mechanism described in this topic in the
375 Inform 6 FAQ (http://www.firthworks.com/roger/informfaq/ww.html#1 How
376 can I get rid of those damn walls?) (except that the compass_look
377 property was previously named compasslook), and means that you no
378 longer need to make the library changes described ther
380 * The verbs "ASK npc TO command" and "TELL npc TO command" -- both
381 synomymous with "npc,command" -- are provided. The new grammar is:
385 * creature 'to' topic -> AskTo
388 in which the creature token matches the npc and the topic token
389 represents the command. AskTo isn’t an action in the usual sense: it's
390 trapped by the parser and converted to the original npc,command
391 format. The npc can intercept the command by providing an orders
392 property in the usual way -- see Section 18 of the Inform Designer’s
395 This enhancement means that you may no longer require Irene Callaci's
396 AskTellOrder.h library extension.
398 * The verbs RECORDING [ON|OFF] and REPLAY are now always available,
399 irrespective of the DEBUG state. This may cause compilation errors if
400 you have already defined these verbs yourself.
402 * The verbs PRY, PRISE, PRIZE and LEVER have been added. This may cause
403 compilation errors if you have already defined these verbs yourself.
405 * The parser treats input lines beginning with “*” as a comment, without
406 attempting any further parsing. The character used to introduce
407 comments can be changed by defining COMMENT_CHARACTER before you
408 "Include Parser;". For example:
410 Constant COMMENT_CHARACTER '!';
412 Since comments are used primarily when capturing a transcript --
413 either of a complete game (SCRIPT ON) or of input commands only
414 (RECORDING ON) -- the parser responds "[Comment recorded]" or
415 "[Comment NOT recorded]" as appropriate.
417 * The selfobj object now includes an empty add_to_scope property, which
418 you can over-ride with your own routine, typically to equip the player
419 with body parts. For a single object:
421 selfobj.add_to_scope = nose;
423 or for multiple object
425 [ IncludeBodyParts; PlaceInScope(nose); PlaceInScope(hands); ];
426 selfobj.add_to_scope = IncludeBodyParts;
428 * The task-based scoring system (§22 of the Inform Designer’s Manual)
429 uses a byte array, which precludes the awarding of large or negative
430 scores. To get round this, you can Replace the TaskScore() library
431 routine as follows, and then define task_scores as a word array:
434 Array task_scores --> 100 200 300 400 (-50) 600;
435 [ TaskScore i; return task_scores-->i; ];
437 * The scoring system is completely disabled if you define a constant
438 NO_SCORE near the start of your game.
442 * A new before_implicit property is available; at the moment this is
443 used only by the parser, when it is about to perform an implicit TAKE
444 (for example, EAT APPLE when you're not holding the apple). You can
445 give this property to an object if you wish to control the parser's
446 behaviour. The property's value should be a constant or a routine
447 which returns: 0 to report "(first taking the...)" and then attempt
448 to do so (this is what currently happens); 1 to attempt the TAKE
449 without first issuing the message, 2 to proceed with the requested
450 action without attempting the TAKE, or 3 to object that "You aren’t
451 holding that!". The object can test action_to_be to determine which
452 action has triggered the TAKE
455 Take: if (action_to_be == ##Eat) return 2;
458 * A new system variable sys_statusline_flag is set to 1 initially if you
459 have used the statusline time; directive in your program to show a
460 clock, and to 0 otherwise. It can be changed by the program.
462 * An object's invent property -- if it has one -- is now invoked both
463 when displaying the player’s inventory and when including the object
464 in a room description. invent is invoked in the usual way (with
465 inventory_stage first set to 1, and then set to 2) both when
466 mentioning the object in a room description, and when listing it in
467 the player's inventory. By default you’ll get the same output each
468 time. If you need to distinguish between the two occasions, you can
469 test (c_style&PARTINV_BIT) -- true during a room description -- or
470 (c_style&FULLINV_BIT) — true during an inventory. Here’s an example:
475 ! When listing objects in the player's inventory
476 if (c_style&FULLINV_BIT) rfalse;
478 ! When listing objects at the end of a room description
479 if (inventory_stage == 1) switch (children(self)) {
480 0: print "an empty sack";
481 1: print "a sack containing ", (a) child(self);
482 default: print "an assortment of objects in a sack";
488 This enhancement uses the mechanism described in
489 http://www.firthworks.com/roger/informfaq/ww.html#4 in the
490 Inform 6 FAQ (Can I avoid printing "(which is empty)" after a
491 container?) and means that you no longer need to Include WriteList.
493 * The turns counter is now initialised to 0, not 1. You can change this
494 if you define a constant START_MOVE near the start of your game.
496 Constant START_MOVE 1;
498 * A new LibraryExtensions object is defined, whose function is to act as
499 a parent to initialisation objects created by library extensions.
500 These objects may provide ext_initialise and/or ext_messages property
501 routines, whose role is to help integrate the extension into a game.
502 This is best explained by example.
504 Consider the SmartCantGo.h extension, which replaces "You can't go
505 that way" messages by the more informative "You can go only north,
506 south and east", and can be integrated into a game by adding a
507 ChangeDefault(cant_go, SmartCantGo) statement to your Initialise()
508 routine. Instead of requiring the author to make this addition, the
509 extension could now cause it to happen automatically by defining an
510 initialisation object as a child of LibraryExtensions, like this:
512 Object "(SmartCantGo)" LibraryExtensions
513 with ext_initialise [; ChangeDefault(cant_go, SmartCantGo); ];
515 Just before calling the game's Initialise() routine, the library loops
516 through the children -- if any -- of LibraryExtensions, and executes
517 those ext_initialise properties that it finds there. The property
518 routines can perform any appropriate setup processing that would
519 otherwise have to be inserted into the Initialise() routine itself;
520 for example, starting a daemon running.
522 A similar process takes place when displaying library messages. The
523 library first checks whether the author has provided a LibraryMessages
524 object to intercept the message which it is about to display. If not,
525 it now loops through the children of LibraryExtensions, and executes
526 ext_messages properties that it finds there. If none of those routines
527 returns true to signal that the message has been dealt with, the
528 standard library text is then printed in the usual way. For example,
529 here’s how an extension might automatically intercept Inventory
530 messages (unless the game has already handled them via LibraryMessages):
532 Object "(someInventoryExtension)" LibraryExtensions
535 1: "You are empty-handed.";
536 2: "Your possessions include";
540 Note that this is an experimental feature, and may be modified or
541 extended in the light of experience.
547 Items of the form [L61036] quote the bug's reference number in the
548 'Library' section of the Inform Patch List at
549 http://inform-fiction.org/patches/library.html
551 * A command like EMPTY ME no longer replies "yourself can't contain
554 * The commands TAKE ALL FROM X and REMOVE ALL FROM X, where X is a
555 closed or empty container, now produce sensible messages rather than
556 "You can’t see any such thing" and "You can’t use multiple objects
557 with that verb" respectively. [L61035]
559 * A problem with the misbehaviour of name properties on rooms, in
560 conjunction with THE, has been corrected. [L61034]
562 * The command PUT X INTO X now correctly produces "You can’t put
563 something inside itself", rather than "You can’t see any such thing".
566 * Run-time errors resulting from IndirectlyContains() attempting to find
567 the parent of a Class which supports dynamic creation of objects have
568 been resolved. [L61032]
570 * Code in Parser__parse() which deals with looking ahead to the indirect
571 object in cases like PUT ALL INTO BAG (a MULTIEXCEPT token) and TAKE
572 ALL FROM BAG (a MULTIINSIDE token) now correctly sets the
573 advance_warning global (to BAG). [L61031, L61023]
575 * The Inform Designer's Manual (p. 98) states that SHOWOBJ should accept
576 an object number; now it does. [L61030]
578 * The YesOrNo() routine now re-prompts correctly after garbage input.
581 * The parse buffer is no longer declared and initialised incorrectly
582 (albeit harmlessly). [L61028, L60708]
584 * The Inform Designer's Manual (p. 93) defines the calling order of
585 routines and properties for the 'Before' stage as follow
587 2. orders of the player
588 3. react_before of every object in scope
589 4. before of the current room
590 5. before of the first noun, if specified
592 In the library, however, steps 3 and 4 are executed in reverse order.
593 They are now as documented. [L61027]
595 * A found_in floating object which the player is able to take (probably
596 due to a coding error) is no longer silently dropped when the player
597 returns to one of the listed rooms. [L61026]
599 * A small problem with inherited describe properties has been corrected.
602 * Standard screen-handling is now implemented in v6 games. [L61022]
604 * The handling of "You can't go that way" messages is made consistent.
605 Also, the statement ChangeDefault(cant_go,myRoutine); now works.
608 * Attempting to place an object in/on an object where it is already now
609 results in "It’s already there", rather than "You need to be holding
610 it before you can put it into something else". [L61019]
612 * A problem with misleading inventory listing has been clarified. [L61018]
614 * The command LEAVE X now correctly produces "But you aren't in/on the
615 X", if appropriate. [L61017]
617 * The response to READ was inappropriate when an object is misspelled or
618 out of scope. [L61016]
620 * A small bug in the choice of library messages for PUSH and TURN, which
621 wasn’t noticeable unless you overrode the messages to be different
622 from PULL, has been corrected. [L61015]
624 * If you are in a dark room, you cannot examine what you are holding.
625 Yet if you open a container you brought in from a lit room, the standard
626 message "You open the box, revealing a..." was not being suppressed.
629 * The ScoreMatchL() routine in Parserm.h incorrectly decided which
630 objects meet descriptors. As a result, some objects that didn't meet
631 descriptors were not properly removed from the match list when the
632 library is deciding which objects best match a player’s input. [L61013]
634 * The Infix problem parsing commands containing commas and periods has
637 * A problem when describing what's visible after opening a container has
638 been corrected. [L61009]
640 * An inappropriate message after GO NORTH CIRCULAR has been corrected.
643 * Modified foreground and background colours are now correct after
644 RESTORE and UNDO. [L61007]
646 * The grammar property now works with a large game whose dictionary lies
647 above $8000. [L61006]
649 * A buffer conflict with disambiguation and UNDO has been resolved.
652 * If a player is inside a closed, non-transparent container, the
653 library prints an extra blank line between the header "The container"
654 and the first inside_description line it prints. No more. [L61002]
656 * The list writing routines do not handle plural containers
657 correctly. If you have two empty boxes, it might list "two boxes
658 (which is closed)". Not only should it say "are closed", but it will
659 lump empty containers together even if some are open and others
660 aren't. Now resolved. [L61001]
662 * A conflict between DrawStatusLine() and DisplayStatus() on how to
663 determine whether to display turns or time is settled in favour of
664 checking a header flag. [L60709]