Object chair "chair" has supporter enterable with name "chair", before [; Take : "It is too big to carted around."; ];If the player attempts to take the chair, "It is too big to be carted around." will be printed and the chair's before routine will return true (1). The action stops and the prompt appears again.
Object chair "chair" has supporter enterable with name "chair", before [; Take : print "It's pretty heavy. "; ];But print "string"; just prints the string and returns 0. So this prints, "It's pretty heavy. " and returns 0. Because processing was not stopped, Inform next calls its built-in library routine, Take, which checks to see if the chair is touchable, if the player is carrying too much already, etc. If all conditions are right, it moves the chair to the player (to the player's inventory) and print_rets, "Taken", returning 1, thus finally stopping further processing. Put together, this is will show on the screen as -- "It's pretty heavy. Taken."
|Knowing what is/returns true or false -- 1 or 0 -- is essential for understanding Inform.|
(end of routine, which returns automatically -- the value
returned depends on the contents, usually 1, but some
routines have a default value)
(prints string and returns 0)
(prints string with a carriage return (new line) and
(prints string with a carriage return (new line) and
returns 1 -- same as above)
(returns from a routine with no value, which is
(returns a specific numeric value)
(returns false -- 0)
(returns true -- 1)
|start of each turn||
Look or New Room
PrintorRun room's initial
1a. A new-line is printed. The location's short name is printed (in bold-face, if possible).
1b. If the player is on a supporter, then " (on <something>)" is printed; if inside anything else, then " (in <something>)".
1c. " (as
1d. A new-line is printed.
Now the `long description'. This step is skipped if the player has just moved of his own will into a location already visited, unless the game is in "verbose" mode.
2. If the location has a describe property, then it is run. If not, the location's description property is looked at: if it's a string, it is printed; if it's a routine, it is run.
All rooms must provide either a describe property or a description of themselves. Now for items nearby:
3a. Any objects on the floor are listed.
3b. If the player is in or on something, the other objects also on/in the supporter/container are listed. The library has now finished, but your game gets a chance to add a postscript.
4. The entry point LookRoutine is called.
Parses the player's input (breaks sentence down into understandable parts).
animate/talkable's grammar routine
An opportunity for your code to interfere with or block altogether what might soon happen.
player's orders' property
react_before of all objects in scope
before of current room
before (action) of first noun
The library takes control and decides if the action makes sense according to its normal world model: for example, only an edible object may be eaten; only an object in the player's possession can be thrown at somebody, and so on. If the action is impossible, a complaint is printed and that's all. Otherwise the action is now carried out.
An opportunity for your code to react to what has happened, after it has happened but before any text announcing it has been printed. If it chooses, your code can print and cause an entirely different outcome. If your code doesn't interfere, the library reports back to the player (with such choice phrases as "Dropped.").
react_after of all objects in scope
after of current room
after of first noun
|end of each turn||
1.The turns counter is incremented.
2.The 24-clock is moved on.
3.Daemons and timers are run (in no guaranteed order).
4. each_turn takes place for the current room, and then for everything nearby (that is, in
5. The game's global TimePasses routine is called.
6. Light is re-considered (it may have changed as a result of events since this time last turn).
[ Initialise; location = field; move lantern to player. "You don't know how you got here. You were just strolling along minding your own business, when this big troll..."; ];Of course, you put the printed string last because that will return true (1).
player = newselfobj;A Doe Crib Note:
When changing the player in
Initialise use the equal sign. When changing the player elsewhere in your
ChangePlayer(newselfobj);. Why? Well, ChangePlayer() performs all kinds of
complicated maneuvers (MoveFloatingObjects(), OffersLight(), etc.) that
Initialise also performs. So if you call ChangePlayer in Initialise, they
will be done twice. Also Zarf recommends = in Initialise. Good
enough for me ;-).
However, if you want the game to report the player's changed state after the room name, (as a dog), then you must use ChangePlayer and use it with a 1 -- ChangePlayer(dog, 1);
Object selfobj "(self object)" <- original player object from parserm.h with short_name [; return L__M(##Miscellany, 18); ], description [; return L__M(##Miscellany, 19); ], before NULL, after NULL, life NULL, each_turn NULL, time_out NULL, describe NULL, capacity 100, parse_name 0, orders 0, number 0, has concealed animate proper transparent; Object newselfobj "(self object)" <- new player object has concealed animate proper transparent with short_name [; return L__M(##Miscellany, 18); ], description [; return L__M(##Miscellany, 19); ], before NULL, after NULL, life NULL, each_turn NULL, time_out NULL, describe NULL, capacity 100, parse_name 0, orders 0, number 0, add_to_scope hands; Object hands "hands" has concealed static transparent with name "hands", article "your", description [; if (gloves has worn) "On your hands are a pair of gloves."; "Your hands are bare."; ], add_to_scope l_hand r_hand; Object l_hand "left hand" with name "left" "hand"; Object r_hand "right hand" with name "right" "hand";
location = office; location = chair;..instead of...
location = office; move player to chair;A Doe Crib Note:
|I have never had a satisfactory explanation of why the first works and the second doesn't. But to start the player on or in an object, use location. It's also a good idea to set the player's location and/or change the player before doing anything else.|
[ Initialise width length i; ! <- local variables location = field; move lantern to player; box "" "There is nothing quite so silly as a bad writer writing a tutorial." "" " Marnie Parker" ""; width = 0->33; if (width == 0) width = 80; if (width > 25) length = (width - 25)/2; else length = 1; style bold; spaces length; print "[Press any key to begin.]"; style roman; @read_char 1 i; @erase_window $ffff; "^^^You don't know how you got here. You were just strolling along minding your own business, when this big troll..." ];width = 0->33; gets the default screen size (in most cases). The rest of that calculation is used to center the prompt, "[Press any key to begin.]" (25 characters). @read_char waits for the player to press a key (any key), and @erase_window clears the screen after the quote box is printed and before the introduction is printed. ^ prints a carriage return without returning 1. It is used here because after clearing the screen the opening sentence may be lost without some preceeding carriage returns.
print "Do you want to restore a saved game? (Y/N) "; if (YesorNo() ~= 0) RestoreSub();
[ Initialise; location = field; move lantern to player. print "You don't know how you got here. You were just strolling along minding your own business, when this big troll...^^"; return 2; ];Note that the banner cannot be permanently skipped. One of Dr. Nelson's conditions granting you the use of Inform, for free, is that you must include the banner near the start of the game, because it lists the Inform compiler and Inform library versions.
Statusline time;before Initialise and after including parser.h. Making a timed game actually work also requires using default Inform routine that should be set in Initialise:
SetTime(hours, rateperturn);Hours is the current time, ratepersturn is how many minutes you want to allot to each turn. The only thing tricky about that is using a 24-hour clock.