Copyright 2014-6 by Andrew Plotkin.
This source code is provided for personal, educational use only. The story and text of Hadean Lands belong to me; you may not use them or create derivative works which contain them. However, you have permission to use the programming techniques of this game in your own works, and you may use the source code excluding game text.
Version 1 of HL Mechanism by Andrew Plotkin begins here.
[### Possible optimization hacks:
- Have a more efficient "move the player without printing a room description" call? Could skip a lot of type checks, and also the SilentlyConsiderLight() function -- at risk of our "pre-check new arrival" rulebook! But this probably isn't called a *whole* lot, even during goal-travel.
- Interpreter option to save undo state to disk, and perhaps without compression. (Have to test.)
- Can any thing-class properties be replaced by sparse (I6) properties? Or ext-object attributes?
- We run the room-visiting activity on every step of goal-travelling. (Which does not mean every single room along the way.) Maybe we can skip the activity? Or have some rules skip themselves for intermediate steps?
- Look for "x=IK2_First: x: x=x.IK2_Link" loops ("all things/everything"). Restrict to subkinds if possible.
]
[### perma-fate for recalling the cedar? Since there's a supply of them. May want to make this a mechanism, for other cases (beaker, mustard, ash)]
Use authorial modesty.
Chapter - Basics
Use American dialect.
Use the serial comma.
Use no scoring.
Use full-length room descriptions.
To say em -- running on:
(- style underline; -).
To say /em -- running on:
(- style roman; -).
To say bold -- running on:
(- style bold; -).
To say /bold -- running on:
(- style roman; -).
To say fixed -- running on:
(- font off; -).
To say /fixed -- running on:
(- font on; -).
To say input -- running on:
(- glk_set_style(style_Input); -).
To say /input -- running on:
(- glk_set_style(style_Normal); -).
To say sarge -- running on:
(- style underline; -).
To say /sarge -- running on:
(- style roman; -).
To say period -- running on:
(- print "."; -).
To say ellipsis -- running on:
(- print "..."; -).
To say question-mark -- running on:
(- print "?"; -).
To say exclam-mark -- running on:
(- print "!"; -).
To say quot -- running on:
(- print "~"; -).
To say br -- running on:
(- new_line; -).
To say para -- running on:
(- DivideParagraphPoint(); new_line; -).
To say going-look-break -- running on:
(- GoingLookBreak(); -);
To say parsermsg:
say italic type;
say bracket.
To say /parsermsg -- running on:
say close bracket;
say roman type.
[Implicitly within a parsermsg paragraph.] [Use a user style on iOS? Nah.]
To say excmd:
say fixed letter spacing;
say "'".
To say /excmd -- running on:
say "'";
say italic type.
To say excmd (T - text) -- running on (this is excmding text):
say "[excmd][T][/excmd]".
To say TheFullRetort:
say "[italic type]The Unanswerable Retort[roman type]".
To say Retort:
say "[italic type]Retort[roman type]".
To say Retort's:
say "[italic type]Retort's[roman type]".
To say it-them (T - thing):
if T is the player:
say "yourself";
else if T is singular-named:
say "it";
else:
say "them".
To say its-their (T - thing):
if T is the player:
say "your";
else if T is singular-named:
say "its";
else:
say "their".
To say That-Those (T - thing):
if T is the player:
say "You";
else if T is singular-named:
say "That";
else:
say "Those".
To say is-are (T - thing):
if T is the player:
say "are";
else if T is singular-named:
say "is";
else:
say "are".
To say doesn't-don't (T - thing):
if T is the player:
say "don't";
else if T is singular-named:
say "doesn't";
else:
say "don't".
To say was-were (T - thing):
if T is the player:
say "were";
else if T is singular-named:
say "was";
else:
say "were".
To say has-have (T - thing):
if T is the player:
say "have";
else if T is singular-named:
say "has";
else:
say "have".
To say has-have (N - number):
if N is 1:
say "has";
else:
say "have".
To say open-closed (T - thing):
if T is open:
say "open";
else:
say "closed".
To say objname (O - object):
[Avoids the mentioned flag of normal name-printing. This should only be used in debug/trace messages.]
(- @push parameter_object; parameter_object = {O}; STANDARD_NAME_PRINTING_R(); @pull parameter_object; -).
To say now-ever-used (O - object):
now O is ever-used.
To decide whether always: (- (1) -).
To decide whether bool (N - word value): (- ({N}) -).
To really decide on nothing: (- return nothing; -).
To break the loop -- in loop: (- break; -).
To continue the loop -- in loop: (- continue; -).
To decide which number is (X - number) bitwise-or (Y - number):
(- ({X} | {Y}) -).
To decide which number is (X - number) bitwise-and (Y - number):
(- ({X} & {Y}) -).
To status cursor pos (N - number): (- VM_MoveCursorInStatusLine(1, {N}); -).
To decide what number is the status line width: (- VM_ScreenWidth() -).
To decide whether (T1 - thing) and (T2 - thing) are jointly (R1 - thing) and (R2 - thing):
if T1 is R1 and T2 is R2:
decide yes;
if T1 is R2 and T2 is R1:
decide yes.
To substitute (T1 - thing) for (T2 - thing):
if T1 is on-stage:
say "(BUG) Tried to substitute [the T1] for [the T2], but [the T1] is on-stage.";
stop;
if T2 is off-stage:
say "(BUG) Tried to substitute [the T1] for [the T2], but [the T2] is off-stage.";
stop;
[We assume that all substitutions are fully known to the player. As with the retirements, we set the fate of T2 and mark it ever-seen/handled.]
now the fate of T2 is transformed-fate;
now the fate-object of T2 is T1;
now T2 is ever-seen;
now T2 is handled;
now T1 is ever-seen;
if T2 is part of something (called composite):
now T1 is part of the composite;
now T2 is off-stage;
stop;
if a container (called cont) contains T2:
now cont contains T1;
now T2 is off-stage;
stop;
if a supporter (called supp) supports T2:
now supp supports T1;
now T2 is off-stage;
stop;
if someone (called carr) carries T2:
now carr carries T1;
now T2 is off-stage;
stop;
if a room (called dest) contains T2:
now T1 is in dest;
now T2 is off-stage;
stop;
say "(BUG) Tried to substitute [the T1] for [the T2], but [the T2] is somewhere incomprehensible ([holder of T2]?)."
To decide what action name is the action-to-be:
(- action_to_be -).
To decide whether the current action is notional:
(- (action == (+ visiting action +) or (+ creating action +) or (+ recalling action +)) -).
To decide whether the action-to-be is notional:
(- (action_to_be == (+ visiting action +) or (+ creating action +) or (+ recalling action +)) -).
To decide whether the current action is not notional:
(- (~~(action == (+ visiting action +) or (+ creating action +) or (+ recalling action +))) -).
To decide whether the action-to-be is not notional:
(- (~~(action_to_be == (+ visiting action +) or (+ creating action +) or (+ recalling action +))) -).
To decide whether the current action is recallish:
(- (action == (+ recalling-all action +) or (+ recalling-formulae action +) or (+ recalling-rituals action +) or (+ recalling-tidbits action +) or (+ recalling-rooms action +) or (+ recalling-things action +) or (+ recalling-doors action +) or (+ recalling action +)) -).
To decide whether the current action is out-of-world:
(- meta -).
To decide whether currently trying silently:
(- keep_silent -).
To decide what object is the untouchable-object:
(- untouchable_object -).
To decide what rulebook outcome is no-outcome: (- 0 -).
To clean up c_style: (- c_style = 0; -).
To decide whether listing tersely:
[We want this condition to catch bucket recital, but *not* locale description paragraphs. The latter always use "brief inventory information" (PARTINV_BIT).]
(- ((c_style & TERSE_BIT) && ~~(c_style & PARTINV_BIT)) -).
To decide whether listing roomily:
(- (c_style & PARTINV_BIT) -).
To decide whether listing inventorily:
(- (c_style & FULLINV_BIT) -).
To decide whether listing details:
[Either roomily or inventorily.]
(- (c_style & (PARTINV_BIT | FULLINV_BIT)) -).
[This selector is 1 for the iOS bound app, 2 for the Lectrote bound app, 0 for general interpreters.]
To decide whether bound-UI: (- (glk_gestalt($2200, 0)) -).
To decide whether iOS-UI: (- (glk_gestalt($2200, 0) == 1) -).
To decide whether Lectrote-UI: (- (glk_gestalt($2200, 0) == 2) -).
To decide what object is paranoid-object-check (N - number): (- ParanoidObjCheck({N}) -).
Include (-
! Return val if val is a valid object, otherwise 0.
[ ParanoidObjCheck val;
if (val < Class + ((#lowest_object_number + #highest_class_number) * GOBJ_TOTAL_LENGTH))
return 0;
if (val > Class + ((#highest_object_number) * GOBJ_TOTAL_LENGTH))
return 0;
if ((val - Class) % GOBJ_TOTAL_LENGTH ~= 0)
return 0;
if (val->0 ~= $70)
return 0;
return val;
];
-).
Section - Bare-Arrays
A bare-array is a kind of value.
To clear (B - bare-array): (- barearray_clear({B}); -).
To decide what number is the limit of (B - bare-array): (- barearray_limit({B}) -).
To decide what number is the count of (B - bare-array): (- ({B})-->1 -).
To decide what object is object (N - number) of (B - bare-array): (- barearray_get({B}, {N}) -).
To change object (N - number) of (B - bare-array) to (O - object): (- barearray_set({B}, {N}, {O}); -).
To decide whether object (O - object) is listed in (B - bare-array): (- barearray_contains({B}, {O}) -).
To decide what number is the position of object (O - object) in (B - bare-array): (- barearray_find({B}, {O}) -).
To add (O - object) to (B - bare-array): (- barearray_append({B}, {O}); -).
To remove last from (B - bare-array): (- barearray_remove_last({B}); -).
To repeat with (loopvar - nonexisting number variable) object (objvar - existing object variable) running through (B - bare-array) begin -- end:
(- for ({loopvar}=0 : {loopvar}<({B})-->1 && ({objvar}=barearray_get({B}, {loopvar}))+1 : {loopvar}++) -).
Barelist-containment relates an object (called O) to a bare-array (called B) when object O is listed in B. The verb to be barelist-in implies the barelist-containment relation.
To say the list of (B - bare-array):
let N be the count of B;
if N is zero:
say "nothing";
else if N is one:
say the object 0 of B;
else if N is two:
say "[the object 0 of B] and [the object 1 of B]";
else:
repeat with index running from 0 to N - 1:
if index is not zero:
if index is N - 1:
say ", and ";
else:
say ", ";
say the object index of B;
Include (-
! arr-->0 is the Inform table size (fixed); arr-->1 is the current count; entries 2 through 11 (ten of them) are the potential entries. Note that the limit is (arr-->0)-1.
Array generic_barearray table 11;
[ barearray_clear arr;
arr-->1 = 0;
];
[ barearray_limit arr;
return (arr-->0) - 1;
];
[ barearray_append arr obj limit pos;
limit = (arr-->0) - 1;
if (arr-->1 >= limit)
print_ret "(BUG) Bare-array append: overflowed limit of ", limit, ".";
pos = arr-->1;
arr-->1 = pos + 1;
arr-->(pos+2) = obj;
];
[ barearray_remove_last arr;
if (arr-->1 == 0) {
print "(BUG) Bare-array remove last: array is empty.^";
return;
}
arr-->1 = (arr-->1) - 1;
];
[ barearray_get arr pos;
if (pos < 0 || pos >= arr-->1) {
print "(BUG) Bare-array get: pos ", pos, " out of range of ", arr-->1, ".^";
return nothing;
}
return arr-->(pos+2);
];
[ barearray_set arr pos val;
if (pos < 0 || pos >= arr-->1) {
print "(BUG) Bare-array set: pos ", pos, " out of range of ", arr-->1, ".^";
return;
}
arr-->(pos+2) = val;
];
[ barearray_contains arr obj ix;
for (ix=0 : ix<arr-->1 : ix++) {
if (arr-->(ix+2) == obj)
rtrue;
}
rfalse;
];
[ barearray_find arr obj ix;
for (ix=0 : ix<arr-->1 : ix++) {
if (arr-->(ix+2) == obj)
return ix;
}
return -1;
];
-).
To decide what bare-array is generic-bare-array: (- generic_barearray -).
Include (-
! This line ensures that we have a recent I6 compiler version. (Needed for Dictionary directives later on.) The stock I6.32 compiler will choke on this.
Undef COMPLETELY_NONEXISTENT_SYMBOL;
-).
Section - Library Customizations
A room has a truth state called recall-minor. [Annexes, nooks, etc. This is a boolean property because I ran into some attribute limit. Make sparse?]
Does the player mean recalling a room:
if the recall-minor of the noun is true:
it is very unlikely;
else:
it is unlikely.
Does the player mean visiting a room:
if the recall-minor of the noun is true:
it is very unlikely;
else:
it is unlikely.
[The action goes crazy in this rulebook -- could be wearing or removing or who knows what.]
Does the player mean rule when the noun is not nothing and the noun is the second noun:
it is very unlikely.
Rule for clarifying the parser's choice of a room:
[Never print "(Nave)", etc.]
stop.
The command-count is a number that varies. [Counts lines input, not turns. Blank lines are ignored, as usual.]
The command-count variable translates into I6 as "command_count".
Include (-
Global command_count = 0;
-) after "Global Variables" in "Output.i6t".
Include (-
[ PrintSpaces n;
while (n > 0) {
print " "; ! two spaces
n = n - 1;
}
];
-) instead of "PrintSpaces" in "Utilities.i6t".
To say indentation (N - number): (- PrintSpaces({N}); -).
To follow (RL - a rule) suppressing breaks:
(- FollowRulebook({RL}, 0, true); -).
To follow (RL - value of kind K based rule producing a value) for (V - K) without suppressing breaks:
(- FollowRulebook({RL}, {V}); -).
Include (-
[ RemoveActionMask acname match mask at;
at = FindAction(acname);
if (at == 0) return;
mask = ActionData-->(at+AD_REQUIREMENTS);
ActionData-->(at+AD_REQUIREMENTS) = mask & (~match);
];
-).
To remove the carried noun requirement for (A - action name): (-
RemoveActionMask({A}, CARRY_NOUN_ABIT);
-).
The namefake-something-object is a proper-named object. The printed name is "something".
The namefake-just-one-thing-object is a proper-named object. The printed name is "just one thing".
To say (N - action name) with direct object (T - object): (- DB_Action_Details({N}, {T}, (+ namefake-something-object +) ); -).
To decide what number is the number of match-list items: (- number_matched -).
To decide what object is the first match-list item: (- GetMatchedItem(0) -).
To decide what object is the second match-list item: (- GetMatchedItem(1) -).
Include (-
[ GetMatchedItem pos;
if (number_matched <= pos)
return nothing;
return match_list-->pos;
];
-).
To decide what action name is the initial action match for verb-word default (N - action name): (- FirstActionMatchForWord(verb_word, {N}) -).
Include (-
[ FirstActionMatchForWord wd def i syntax num_lines line_address res;
i = DictionaryWordToVerbNum(wd);
if (~~i)
return def;
syntax = (#grammar_table)-->(i+1);
if (~~syntax)
return def;
num_lines = (syntax->0) - 1;
if (~~num_lines)
return def;
line_address = syntax + 1;
@aloads line_address 0 res;
return res;
];
-).
To decide what number is the start of (S - snippet): (- ({S}/100) -).
To decide what number is the length of (S - snippet): (- ({S}%100) -).
To decide what snippet is snippet starting at (N - number) with length (L - number): (- (({N})*100+({L})) -).
To decide whether word (N - number) of the buffer is comma-like: (- (WordFrom({N}, parse) == comma_word or THEN1__WD or AND1__WD) -).
Include (-
[ Refers obj wnum wd k l m;
if (obj == 0) rfalse;
#Ifdef LanguageRefers;
k = LanguageRefers(obj,wnum); if (k >= 0) return k;
#Endif; ! LanguageRefers
k = wn; wn = wnum; wd = NextWordStopped(); wn = k;
if (parser_inflection >= 256) {
k = indirect(parser_inflection, obj, wd);
if (k >= 0) return k;
m = -k;
}
else
m = parser_inflection;
k = obj.&m; l = (obj.#m)/WORDSIZE-1;
for (m=0 : m<=l : m++)
if (wd == k-->m) rtrue;
rfalse;
];
[ WordInProperty wd obj prop k l m;
k = obj.∝ l = (obj.#prop)/WORDSIZE-1;
for (m=0 : m<=l : m++)
if (wd == k-->m) rtrue;
if (wd == 'the') rtrue;
rfalse;
];
-) instead of "Refers" in "Parser.i6t".
To decide whether player consents-or-restores: (- YesOrNo(true) -).
Include (-
! Bonus feature: Can accept "yes", "no", or "restore" (if requested).
[ YesOrNo canrestore i j;
for (::) {
#Ifdef TARGET_ZCODE;
if (location == nothing || parent(player) == nothing) read buffer parse;
else read buffer parse DrawStatusLine;
j = parse->1;
#Ifnot; ! TARGET_GLULX;
KeyboardPrimitive(buffer, parse);
BufferStripPunctuation();
j = parse-->0;
#Endif; ! TARGET_
if (j) { ! at least one word entered
i = parse-->1;
if (i == YES1__WD or YES2__WD or YES3__WD) rtrue;
if (i == NO1__WD or NO2__WD or NO3__WD) rfalse;
if (canrestore && i == RESTORE__WD) {
RESTORE_THE_GAME_R();
! If it failed, we've printed a message; skip the "please enter yes or no" line.
print ">> ";
continue;
}
}
L__M(##Quit, 1); print "> ";
}
];
-) instead of "Yes/No Questions" in "Parser.i6t".
Include (-
[ BufferStartsWithStar;
if (num_words && WordAddress(1)->0 == '*')
rtrue;
rfalse;
];
! Returns true if any punctuation is removed.
[ BufferStripPunctuation len ix count;
len = buffer-->0;
count = 0;
for (ix=0 : ix<len : ix++) {
if (buffer->(4+ix) == '(' or ')' or '?' or '!') {
buffer->(4+ix) = ' ';
count++;
}
}
if (count) {
VM_Tokenise(buffer, parse);
players_command = 100 + WordCount();
rtrue;
}
rfalse;
];
-).
A thing can be low-locale-priority. A thing is usually not low-locale-priority.
A thing can be prominent-scenery. A thing is usually not prominent-scenery.
A prominent-scenery thing is usually scenery. [An implication.]
The custom notable locale objects rule is listed instead of the standard notable locale objects rule in the for choosing notable locale objects rulebook.
For choosing notable locale objects (this is the custom notable locale objects rule):
let the domain be the parameter-object;
let the held item be the first thing held by the domain;
while the held item is a thing:
if the held item is low-locale-priority:
set the locale priority of the held item to 7;
else if the held item is scenery or the held item is fixed in place:
set the locale priority of the held item to 3;
else:
set the locale priority of the held item to 5;
now the held item is the next thing held after the held item;
continue the activity.
[We can suppress the display-suppressing properties of scenery by making them prominent-scenery.]
The conditional don't mention scenery in room descriptions rule is listed instead of the don't mention scenery in room descriptions rule in the for printing a locale paragraph about rulebook.
For printing a locale paragraph about a thing (called the item)
(this is the conditional don't mention scenery in room descriptions rule):
if the item is scenery and the item is not prominent-scenery:
set the locale priority of the item to 0;
continue the activity.
[Suppress the pronoun-setting behavior of this rule.]
The pronounless describe what's on scenery supporters in room descriptions rule is listed instead of the describe what's on scenery supporters in room descriptions rule in the for printing a locale paragraph about rulebook.
For printing a locale paragraph about a thing (called the item)
(this is the pronounless describe what's on scenery supporters in room descriptions rule):
if the item is [not undescribed and the item is] scenery and
the item does not enclose the player:
if a locale-supportable thing is on the item:
[set pronouns from the item;]
repeat with possibility running through things on the item:
now the possibility is marked for listing;
if the possibility is mentioned:
now the possibility is not marked for listing;
increase the locale paragraph count by 1;
say "On [the item] ";
list the contents of the item, as a sentence, including contents,
giving brief inventory information, tersely, not listing
concealed items, prefacing with is/are, listing marked items only;
say ".[paragraph break]";
continue the activity.
The set pronouns from items in room descriptions rule is not listed in any rulebook.
Include (-
Constant MANUAL_PRONOUNS 1;
-) before "Pronoun Handling" in "Parser.i6t".
The roomily search containers rule is listed instead of the standard search containers rule in the report searching rulebook.
Report searching a container (this is the roomily search containers rule):
if the noun contains a described thing which is not scenery:
say "In [the noun] ";
list the contents of the noun, as a sentence, tersely, not listing concealed items, prefacing with is/are, giving brief inventory information;
say ".";
else:
say "[The noun] [is-are noun] empty."
The roomily search supporters rule is listed instead of the standard search supporters rule in the report searching rulebook.
Report searching a supporter (this is the roomily search supporters rule):
if the noun supports a described thing which is not scenery:
say "On [the noun] ";
list the contents of the noun, as a sentence, tersely, not listing concealed items, prefacing with is/are, giving brief inventory information;
say ".";
else:
say "There is nothing on [the noun]."
Check an actor exiting (this is the unconditionally convert exit into go out rule):
let the local room be the location of the actor;
[The Standard Rules only do this when there's an "out" exit, but we want to catch it always.]
if the container exited from is the local room:
convert to the going action on the outside.
The unconditionally convert exit into go out rule is listed instead of the convert exit into go out rule in the check exiting rulebook.
Check an actor vague-entering (this is the unconditionally convert enter into go in rule):
convert to the going action on the inside.
A room has a text called the can't-go. The can't-go of a room is usually "".
Check an actor going (this is the property-based can't go that way rule):
if the room gone to is nothing:
if the door gone through is nothing:
[stop the action with library message going action number 2 for the room gone from;]
let C be the can't-go of the room gone from;
if C is "":
now C is "You can't go that way.";
say "[C][line break]";
stop the action;
stop the action with library message going action number 6 for the door gone through.
The property-based can't go that way rule is listed instead of the can't go that way rule in the check going rulebook.
Include (-
#ifdef DEBUG;
! Exactly once, we check that found_in properties are sane.
Global MFO_sanity_check = true;
#endif;
! Simplify: Only loop over the I7 door and backdrop classes. Do not remove objects from play when they're not found.
! We assume that doors have the default two-room found_in property. Backdrops can have any of the usual found_in structures.
[ MoveFloatingObjects i k l m address flag;
if (real_location == nothing) return;
! Make sure that class 7 is doors (so IK7_First/IK7_Link work).
if (KindHierarchy-->(2*7) ~= K7_backdrop)
print "(BUG) Class 7 is not backdrop";
for (i = IK7_First; i; i = i.IK7_Link) {
address = i.&found_in;
if (address ~= 0 && i hasnt absent) {
if (ZRegion(address-->0) == 2) {
m = address-->0;
.TestPropositionally;
if (m.call(real_location) ~= 0) move i to real_location;
else remove i;
}
else {
k = i.#found_in;
for (l=0 : l<k/WORDSIZE : l++) {
m = address-->l;
if (ZRegion(m) == 2) jump TestPropositionally;
if (m == real_location || m in real_location) {
if (i notin real_location) move i to real_location;
flag = true;
}
}
if (flag == false) { remove i; }
}
}
}
! Make sure that class 4 is doors (so IK4_First/IK4_Link work).
if (KindHierarchy-->(2*4) ~= K4_door)
print "(BUG) Class 4 is not door";
for (i = IK4_First; i; i = i.IK4_Link) {
#ifdef DEBUG;
if (MFO_sanity_check) {
if (i.&found_in == 0)
print "(BUG) Door ", (name) i, " has no found_in.";
if (i.#found_in ~= 2*WORDSIZE)
print "(BUG) Door ", (name) i, " has wrong size found_in.";
}
#endif;
if (i has absent)
continue;
address = i.&found_in;
if (address-->0 == real_location || address-->1 == real_location) {
if (i notin real_location) move i to real_location;
}
}
#ifdef DEBUG;
MFO_sanity_check = false;
#endif;
];
! No changes
[ MoveBackdrop bd D x address;
if (~~(bd ofclass K7_backdrop)) return RunTimeProblem(RTP_BACKDROPONLY, bd);
if (bd.#found_in > WORDSIZE) {
address = bd.&found_in;
address-->0 = D;
} else bd.found_in = D;
give bd ~absent;
MoveFloatingObjects();
];
-) instead of "Floating Objects" in "WorldModel.i6t".
To completely suppress paragraph newlines: (- suppress_extra_newlines = 1; -).
To restore paragraph newlines: (- suppress_extra_newlines = 0; ClearParagraphing(); -).
Include (-
Global suppress_extra_newlines = 0;
[ DivideParagraphPoint;
#ifdef TRACE_I7_SPACING; print "[DPP", say__p, say__pc, "]"; #endif;
if (say__p) {
if (suppress_extra_newlines == 0) new_line;
say__p = 0; say__pc = say__pc | PARA_COMPLETED;
if (say__pc & PARA_PROMPTSKIP) say__pc = say__pc - PARA_PROMPTSKIP;
if (say__pc & PARA_SUPPRESSPROMPTSKIP) say__pc = say__pc - PARA_SUPPRESSPROMPTSKIP;
}
#ifdef TRACE_I7_SPACING; print "[-->", say__p, say__pc, "]"; #endif;
say__pc = say__pc | PARA_CONTENTEXPECTED;
];
! The rest of this is cloned from Printing.i6t without change.
[ ClearParagraphing;
say__p = 0; say__pc = 0;
];
[ ParaContent;
if (say__pc & PARA_CONTENTEXPECTED) {
say__pc = say__pc - PARA_CONTENTEXPECTED;
say__p = 1;
}
];
[ GoingLookBreak;
if (say__pc & PARA_COMPLETED == 0) new_line;
ClearParagraphing();
];
[ CommandClarificationBreak;
new_line;
ClearParagraphing();
];
[ RunParagraphOn;
#ifdef TRACE_I7_SPACING; print "[RPO", say__p, say__pc, "]"; #endif;
say__p = 0;
say__pc = say__pc | PARA_PROMPTSKIP;
say__pc = say__pc | PARA_SUPPRESSPROMPTSKIP;
];
[ SpecialLookSpacingBreak;
#ifdef TRACE_I7_SPACING; print "[SLS", say__p, say__pc, "]"; #endif;
say__p = 0;
say__pc = say__pc | PARA_PROMPTSKIP;
];
[ EnsureBreakBeforePrompt;
if ((say__p) ||
((say__pc & PARA_PROMPTSKIP) && ((say__pc & PARA_SUPPRESSPROMPTSKIP)==0)))
new_line;
ClearParagraphing();
];
[ PrintSingleParagraph matter;
say__p = 1;
say__pc = say__pc | PARA_NORULEBOOKBREAKS;
PrintText(matter);
DivideParagraphPoint();
say__pc = 0;
];
-) instead of "State" in "Printing.i6t";
To say (something - number) in wordsth:
(- print (LanguageNumberth) say__n=({something}); -).
To say (something - number) in capital words:
(- print (CapLanguageNumber) say__n=({something}); -).
To say (something - number) in words cap (flag - word value):
(- if ({flag}) print (CapLanguageNumber) say__n=({something}); else print (LanguageNumber) say__n=({something}); -).
Include (-
! Only covers -20 through 20, because that's all I need right now.
[ LanguageNumberth val;
if (val == 0) {
print "zeroth";
return;
}
if (val < 0) {
print "minus ";
val = -val;
}
switch (val) {
1: print "first";
2: print "second";
3: print "third";
4: print "fourth";
5: print "fifth";
6: print "sixth";
7: print "seventh";
8: print "eighth";
9: print "ninth";
10: print "tenth";
11: print "eleventh";
12: print "twelfth";
13: print "thirteenth";
14: print "fourteenth";
15: print "fifteenth";
16: print "sixteenth";
17: print "seventeenth";
18: print "eighteenth";
19: print "nineteenth";
20: print "twentieth";
default: print "(BUG)th";
}
];
[ CapLanguageNumber val;
if (val == 0) {
print "Zero";
return;
}
if (val < 0) {
print "Minus ";
LanguageNumber(-val);
return;
}
switch (val) {
1: print "One";
2: print "Two";
3: print "Three";
4: print "Four";
5: print "Five";
6: print "Six";
7: print "Seven";
8: print "Eight";
9: print "Nine";
10: print "Ten";
11: print "Eleven";
12: print "Twelve";
13: print "Thirteen";
14: print "Fourteen";
15: print "Fifteen";
16: print "Sixteen";
17: print "Seventeen";
18: print "Eighteen";
19: print "Nineteen";
20: print "Twenty";
default: print val;
}
];
-);
Include (-
[ Banner;
BeginActivity(PRINTING_BANNER_TEXT_ACT);
if (ForActivity(PRINTING_BANNER_TEXT_ACT) == false) {
VM_Style(HEADER_VMSTY);
print (string) Story;
VM_Style(NORMAL_VMSTY);
new_line;
print (string) Headline;
#ifdef Story_Author;
print " by ", (string) Story_Author;
#endif; ! Story_Author
new_line;
#ifdef Story_Attribution;
print (string) Story_Attribution;
new_line;
#endif; ! Story_Attribution
VM_Describe_Release();
print " / Inform 7 build ", (string) NI_BUILD_COUNT, " ";
print "(I6/v"; inversion;
!print " lib ", (string) LibRelease;
print ") ";
#Ifdef STRICT_MODE;
print "S";
#Endif; ! STRICT_MODE
#Ifdef DEBUG;
print "D";
#Endif; ! DEBUG
new_line;
}
EndActivity(PRINTING_BANNER_TEXT_ACT);
];
-) instead of "Banner" in "Printing.i6t".
The custom announce the story file version rule is listed instead of the announce the story file version rule in the carry out requesting the story file version rulebook.
The custom announce the story file version rule translates into I6 as "CUSTOM_STORY_FILE_VERSION_R".
Include (-
[ CUSTOM_STORY_FILE_VERSION_R ix val;
if (actor ~= player) rfalse;
Banner();
print "Identification number: ";
for (ix=6: ix <= UUID_ARRAY->0: ix++) print (char) UUID_ARRAY->ix;
print "^";
@gestalt 1 0 ix;
print "Interpreter version ", ix / $10000, ".", (ix & $FF00) / $100,
".", ix & $FF, " / ";
val = glk_gestalt($2200, 0); ! check bound-UI gestalt
switch (val) {
0: break;
1: print "iOS app / ";
2: print "Lectrote app / ";
default: print "app ", val, "? / ";
}
@gestalt 0 0 ix;
print "VM ", ix / $10000, ".", (ix & $FF00) / $100, ".", ix & $FF, " / ";
print "Library serial number ", (string) LibSerial, "^";
#Ifdef LanguageVersion;
print (string) LanguageVersion, "^";
#Endif; ! LanguageVersion
ShowExtensionVersions();
say__p = 1;
];
[ ANNOUNCE_STORY_FILE_VERSION_R;
! Never called, but it has to be defined.
];
-) instead of "Announce Story File Version Rule" in "Glulx.i6t".
Include (-
[ SWITCH_TRANSCRIPT_ON_R;
if (actor ~= player) rfalse;
if (gg_scriptstr ~= 0) return GL__M(##ScriptOn, 1);
.S2Failed;
if (gg_scriptfref == 0) {
gg_scriptfref = glk_fileref_create_by_prompt($102, $05, GG_SCRIPTFREF_ROCK);
if (gg_scriptfref == 0) jump S1Failed;
}
! stream_open_file
gg_scriptstr = glk_stream_open_file(gg_scriptfref, $05, GG_SCRIPTSTR_ROCK);
if (gg_scriptstr == 0) {
! Could not open selected file; select again
glk_fileref_destroy(gg_scriptfref);
gg_scriptfref = 0;
jump S2Failed;
}
glk_window_set_echo_stream(gg_mainwin, gg_scriptstr);
GL__M(##ScriptOn, 2);
VersionSub();
return;
.S1Failed;
GL__M(##ScriptOn, 3);
];
-) instead of "Switch Transcript On Rule" in "Glulx.i6t".
Include (-
Global wn_at_upto_pe = 0; ! saves wn when we generate UPTO_PE
-) before "Parser.i6t".
[This chunk has a couple of tiny changes:
- The Examine action bails out at the first multi-object error ("can't use multiple objects error"), instead of continuing to later grammar lines. This works around the obscure bug where "examine impets" throws an "noun did not make sense in that context error" instead of the multi-objects one.
- When the UPTO_PE ("only understood as far as...") error occurs, we save the current value of wn in a global. This is necessary for printing a verbose parser error.
]
Include (-
for (pcount=1 : : pcount++) {
pattern-->pcount = PATTERN_NULL; scope_token = 0;
token = line_token-->(pcount-1);
lookahead = line_token-->pcount;
#Ifdef DEBUG;
if (parser_trace >= 2)
print " [line ", line, " token ", pcount, " word ", wn, " : ", (DebugToken) token,
"]^";
#Endif; ! DEBUG
if (token ~= ENDIT_TOKEN) {
scope_reason = PARSING_REASON;
AnalyseToken(token);
l = ParseToken(found_ttype, found_tdata, pcount-1, token);
while ((l >= GPR_NOUN) && (l < -1)) l = ParseToken(ELEMENTARY_TT, l + 256);
scope_reason = PARSING_REASON;
if (l == GPR_PREPOSITION) {
if (found_ttype~=PREPOSITION_TT && (found_ttype~=ELEMENTARY_TT ||
found_tdata~=TOPIC_TOKEN)) params_wanted--;
l = true;
}
else
if (l < 0) l = false;
else
if (l ~= GPR_REPARSE) {
if (l == GPR_NUMBER) {
if (nsns == 0) special_number1 = parsed_number;
else special_number2 = parsed_number;
nsns++; l = 1;
}
if (l == GPR_MULTIPLE) l = 0;
parser_results-->(parameters+INP1_PRES) = l;
parameters++;
pattern-->pcount = l;
l = true;
}
#Ifdef DEBUG;
if (parser_trace >= 3) {
print " [token resulted in ";
if (l == REPARSE_CODE) print "re-parse request]^";
if (l == 0) print "failure with error type ", etype, "]^";
if (l == 1) print "success]^";
}
#Endif; ! DEBUG
if (l == REPARSE_CODE) jump ReParse;
if (l == false) break;
}
else {
! If the player has entered enough already but there's still
! text to wade through: store the pattern away so as to be able to produce
! a decent error message if this turns out to be the best we ever manage,
! and in the mean time give up on this line
! However, if the superfluous text begins with a comma or "then" then
! take that to be the start of another instruction
if (wn <= num_words) {
l = NextWord();
if (l == THEN1__WD or THEN2__WD or THEN3__WD or comma_word) {
held_back_mode = 1; hb_wn = wn-1;
}
else {
for (m=0 : m<32 : m++) pattern2-->m = pattern-->m;
pcount2 = pcount;
wn_at_upto_pe = wn; ! --ZARF: save wn value
etype = UPTO_PE;
break;
}
}
! Now, we may need to revise the multiple object because of the single one
! we now know (but didn't when the list was drawn up).
if (parameters >= 1 && parser_results-->INP1_PRES == 0) {
l = ReviseMulti(parser_results-->INP2_PRES);
if (l ~= 0) { etype = l; parser_results-->ACTION_PRES = action_to_be; break; }
}
if (parameters >= 2 && parser_results-->INP2_PRES == 0) {
l = ReviseMulti(parser_results-->INP1_PRES);
if (l ~= 0) { etype = l; break; }
}
! To trap the case of "take all" inferring only "yourself" when absolutely
! nothing else is in the vicinity...
if (take_all_rule == 2 && parser_results-->INP1_PRES == actor) {
best_etype = NOTHING_PE;
jump GiveError;
}
#Ifdef DEBUG;
if (parser_trace >= 1) print "[Line successfully parsed]^";
#Endif; ! DEBUG
! The line has successfully matched the text. Declare the input error-free...
oops_from = 0;
! ...explain any inferences made (using the pattern)...
if (inferfrom ~= 0) {
PrintInferredCommand(inferfrom);
ClearParagraphing();
}
! ...copy the action number, and the number of parameters...
parser_results-->ACTION_PRES = action_to_be;
parser_results-->NO_INPS_PRES = parameters;
! ...reverse first and second parameters if need be...
if (action_reversed && parameters == 2) {
i = parser_results-->INP1_PRES;
parser_results-->INP1_PRES = parser_results-->INP2_PRES;
parser_results-->INP2_PRES = i;
if (nsns == 2) {
i = special_number1; special_number1 = special_number2;
special_number2 = i;
}
}
! ...and to reset "it"-style objects to the first of these parameters, if
! there is one (and it really is an object)...
if (parameters > 0 && parser_results-->INP1_PRES >= 2)
PronounNotice(parser_results-->INP1_PRES);
! ...and return from the parser altogether, having successfully matched
! a line.
if (held_back_mode == 1) {
wn=hb_wn;
jump LookForMore;
}
rtrue;
} ! end of if(token ~= ENDIT_TOKEN) else
} ! end of for(pcount++)
.LineFailed;
! The line has failed to match.
! We continue the outer "for" loop, trying the next line in the grammar.
if (etype > best_etype) best_etype = etype;
if (etype ~= ASKSCOPE_PE && etype > nextbest_etype) nextbest_etype = etype;
! ...unless the line was something like "take all" which failed because
! nothing matched the "all", in which case we stop and give an error now.
if (take_all_rule == 2 && etype==NOTHING_PE) break;
if (action_to_be == ##Examine && etype == MULTI_PE) break; ! --ZARF: added case
} ! end of for(line++)
! The grammar is exhausted: every line has failed to match.
-) instead of "Parser Letter G" in "Parser.i6t".
[When the UPTO_PE ("only understood as far as...") error occurs, we save the current value of wn in a global. This is necessary for printing a verbose parser error.]
Include (-
! At this point, the return value is all prepared, and we are only looking
! to see if there is a "then" followed by subsequent instruction(s).
.LookForMore;
if (wn > num_words) rtrue;
i = NextWord();
if (i == THEN1__WD or THEN2__WD or THEN3__WD or comma_word) {
if (wn > num_words) {
held_back_mode = false;
return;
}
i = WordAddress(verb_wordnum);
j = WordAddress(wn);
for (: i<j : i++) i->0 = ' ';
i = NextWord();
if (i == AGAIN1__WD or AGAIN2__WD or AGAIN3__WD) {
! Delete the words "then again" from the again buffer,
! in which we have just realised that it must occur:
! prevents an infinite loop on "i. again"
i = WordAddress(wn-2)-buffer;
if (wn > num_words) j = INPUT_BUFFER_LEN-1;
else j = WordAddress(wn)-buffer;
for (: i<j : i++) buffer3->i = ' ';
}
VM_Tokenise(buffer,parse);
held_back_mode = true;
return;
}
wn_at_upto_pe = wn; ! --ZARF: save wn value
best_etype = UPTO_PE;
jump GiveError;
-) instead of "Parser Letter K" in "Parser.i6t".
Section - List-Writing Customizations
[We save the "cl" argument in a global, so that grouping-together rules can capitalize adequately.]
To decide what number is cap-class-group: (- (capitalize_class_group) -).
Include (-
Global capitalize_class_group;
[ WriteMultiClassGroup cl memb depth partition_class_sizes q k2 l;
! Save the style, because the activity below is allowed to change it
q = c_style;
if (c_style & INDENT_BIT ~= 0) PrintSpaces(2*(depth+c_margin));
capitalize_class_group = ((cl == 1) && (c_style & CFIRSTART_BIT));
BeginActivity(GROUPING_TOGETHER_ACT, memb);
if (ForActivity(GROUPING_TOGETHER_ACT, memb)) {
c_style = c_style &~ NEWLINE_BIT;
} else {
if (memb.list_together ofclass String) {
! Set k2 to the number of objects covered by the group
k2 = 0;
for (l=0 : l<listing_size : l++) k2 = k2 + partition_class_sizes->(l+cl);
EnglishNumber(k2); print " ";
print (string) memb.list_together;
if (c_style & ENGLISH_BIT ~= 0) print " (";
if (c_style & INDENT_BIT ~= 0) print ":^";
} else {
inventory_stage = 1;
parser_one = memb; parser_two = depth + c_margin;
if (RunRoutines(memb, list_together) == 1) jump Omit__Sublist2;
}
c_margin++;
@push capitalize_class_group; @push lt_value; @push listing_together; @push listing_size;
lt_value = memb.list_together; listing_together = memb;
#Ifdef DBLW; print "^^DOWN lt_value = ", lt_value, " listing_together = ", memb, "^^";
@push DBLW_no_classes; @push DBLW_no_objs; #Endif;
WriteListR(memb, depth, false);
#Ifdef DBLW; print "^^UP^^"; @pull DBLW_no_objs; @pull DBLW_no_classes; #Endif;
@pull listing_size; @pull listing_together; @pull lt_value; @pull capitalize_class_group;
c_margin--;
if (memb.list_together ofclass String) {
if (q & ENGLISH_BIT ~= 0) print ")";
} else {
inventory_stage = 2;
parser_one = memb; parser_two = depth+c_margin;
RunRoutines(memb, list_together);
}
.Omit__Sublist2;
}
EndActivity(GROUPING_TOGETHER_ACT, memb);
! If the NEWLINE_BIT has been forced by the activity, act now
! before it vanishes...
if (q & NEWLINE_BIT ~= 0 && c_style & NEWLINE_BIT == 0) new_line;
! ...when the original style is restored again:
c_style = q;
];
-) instead of "Write Multiple Class Group" in "ListWriter.i6t".
[Comment out the code that clears and resets list_together. We do that statically, at startup.
We also use a somewhat more efficient loop to set the list_filter_permits attribute.]
Include (-
! Set/clear the list_filter_permits attribute. We optimize on the assumption that
! list_filter_routine is always "a is mentioned", which is a tiny but nonzero
! improvement.
! Do this recursively on the object and its contents (if any).
[ ListFilterContents a o;
if ((list_filter_routine) && (a has mentioned))
give a ~list_filter_permits;
else
give a list_filter_permits;
objectloop (o in a) {
ListFilterContents(o);
}
];
[ WriteListFrom first style depth noactivity iter i a;
@push c_iterator; @push c_style; @push c_depth; @push c_margin;
if (iter) c_iterator = iter; else c_iterator = ObjectTreeIterator;
c_style = style; c_depth = depth;
c_margin = 0; if (style & EXTRAINDENT_BIT) c_margin = 1;
! Set or clear the list_filter_permits flag. Try to do it efficiently.
if (c_iterator == ObjectTreeIterator) {
! For the tree iterator, we follow the tree.
for (a = first : a : a = sibling(a)) {
ListFilterContents(a);
}
}
else if (c_iterator == MarkedListIterator) {
! For the list iterator, we follow the list.
for (i=0: i<MarkedObjectLength: i++) {
a = MarkedObjectArray-->i;
ListFilterContents(a);
}
}
else {
! The sad inefficient old way -- loops through all objects.
! (We don't bother with recursion because we're hitting all objects
! anyway.)
objectloop (a ofclass Object) {
if ((list_filter_routine) && (a has mentioned))
give a ~list_filter_permits;
else
give a list_filter_permits;
}
}
first = c_iterator(first, depth, 0, START_ITF);
if (first == nothing) {
print (string) NOTHING__TX;
if (style & NEWLINE_BIT ~= 0) new_line;
} else {
if ((noactivity) || (iter)) {
WriteListR(first, c_depth, true);
say__p = 1;
} else {
!objectloop (ol provides list_together) ol.list_together = 0;
CarryOutActivity(LISTING_CONTENTS_ACT, parent(first));
}
}
@pull c_margin; @pull c_depth; @pull c_style; @pull c_iterator;
];
! This does the work of WriteListFrom, with a style and details activities, but only names a single object. (ISARE_BIT is ignored.)
[ WriteListSingleton obj style;
@push c_iterator; @push c_style; @push c_depth; @push c_margin;
c_iterator = nothing;
c_style = style; c_depth = 0;
c_margin = 0; if (style & EXTRAINDENT_BIT) c_margin = 1;
ListFilterContents(obj);
if (obj == nothing) {
print (string) NOTHING__TX;
if (style & NEWLINE_BIT ~= 0) new_line;
} else {
! WriteListR() is iterator-oriented, so we include a cut-down version of it.
WriteSingleClassGroup(1, obj, c_depth, 1);
say__p = 1;
}
@pull c_margin; @pull c_depth; @pull c_style; @pull c_iterator;
];
-) instead of "WriteListFrom" in "ListWriter.i6t".
Include (-
[ WriteListOfMarkedContentsObjects style common_parent
obj first length;
objectloop (obj in common_parent && obj has workflag2) {
length++;
if (first == nothing) { first = obj; }
}
if (length == 0) {
if (style & ISARE_BIT ~= 0) print (string) IS3__TX, " ", (string) NOTHING__TX;
else if (style & CFIRSTART_BIT ~= 0) print (string) NOTHING2__TX;
else print (string) NOTHING__TX;
} else {
@push MarkedObjectArray; @push MarkedObjectLength;
MarkedObjectArray = RequisitionStack(length);
MarkedObjectLength = length;
if (MarkedObjectArray == 0) return RunTimeProblem(RTP_LISTWRITERMEMORY);
! common_parent is always set
ObjectTreeCoalesce(child(common_parent));
length = 0;
objectloop (obj in common_parent) ! object tree order
if (obj has workflag2) MarkedObjectArray-->length++ = obj;
WriteListFrom(first, style, 0, false, MarkedListIterator);
FreeStack(MarkedObjectArray);
@pull MarkedObjectLength; @pull MarkedObjectArray;
}
return;
];
-) after "WriteListOfMarkedObjects" in "ListWriter.i6t".
[Copy the "inventory details" activity hook from 6L02.]
Printing inventory details of something is an activity.
Include (-
[ WriteAfterEntry o depth
p recurse_flag parenth_flag eldest_child child_count combo;
inventory_stage = 2;
if (c_style & PARTINV_BIT) {
BeginActivity(PRINTING_ROOM_DESC_DETAILS_ACT);
if (ForActivity(PRINTING_ROOM_DESC_DETAILS_ACT) == false) {
combo = 0;
if (o has light && location hasnt light) combo=combo+1;
if (o has container && o hasnt open) combo=combo+2;
if ((o has container && (o has open || o has transparent))
&& (child(o)==0)) combo=combo+4;
if (combo) L__M(##ListMiscellany, combo, o);
}
EndActivity(PRINTING_ROOM_DESC_DETAILS_ACT);
} ! end of PARTINV_BIT processing
if (c_style & FULLINV_BIT) {
BeginActivity((+ printing inventory details +), o);
if (ForActivity((+ printing inventory details +), o) == false) {
if (o has light && o has worn) { L__M(##ListMiscellany, 8, o); parenth_flag = true; }
else {
if (o has light) { L__M(##ListMiscellany, 9, o); parenth_flag = true; }
if (o has worn) { L__M(##ListMiscellany, 10, o); parenth_flag = true; }
}
if (o has container)
if (o has openable) {
if (parenth_flag) {
#Ifdef SERIAL_COMMA; print ","; #Endif;
print (string) AND__TX;
} else L__M(##ListMiscellany, 11, o);
if (o has open)
if (child(o)) L__M(##ListMiscellany, 12, o);
else L__M(##ListMiscellany, 13, o);
else
if (o has lockable && o has locked) L__M(##ListMiscellany, 15, o);
else L__M(##ListMiscellany, 14, o);
parenth_flag = true;
}
else
if (child(o)==0 && o has transparent)
if (parenth_flag) L__M(##ListMiscellany, 16, o);
else L__M(##ListMiscellany, 17, o);
if (parenth_flag) print ")";
}
EndActivity((+ printing inventory details +), o);
} ! end of FULLINV_BIT processing
child_count = 0;
eldest_child = nothing;
objectloop (p in o)
if ((c_style & CONCEAL_BIT == 0) || (p hasnt concealed && p hasnt scenery))
if (p has list_filter_permits) {
child_count++;
if (eldest_child == nothing) eldest_child = p;
}
if (child_count && (c_style & ALWAYS_BIT)) {
if (c_style & ENGLISH_BIT) L__M(##ListMiscellany, 18, o);
recurse_flag = true;
}
if (child_count && (c_style & RECURSE_BIT)) {
if (o has supporter) {
if (c_style & ENGLISH_BIT) {
if (c_style & TERSE_BIT) L__M(##ListMiscellany, 19, o);
else L__M(##ListMiscellany, 20, o);
if (o has animate) print (string) WHOM__TX;
else print (string) WHICH__TX;
}
recurse_flag = true;
}
if (o has container && (o has open || o has transparent)) {
if (c_style & ENGLISH_BIT) {
if (c_style & TERSE_BIT) L__M(##ListMiscellany, 21, o);
else L__M(##ListMiscellany, 22, o);
if (o has animate) print (string) WHOM__TX;
else print (string) WHICH__TX;
}
recurse_flag = true;
}
}
if (recurse_flag && (c_style & ENGLISH_BIT))
if (child_count > 1 || eldest_child has pluralname) print (string) ARE2__TX;
else print (string) IS2__TX;
if (c_style & NEWLINE_BIT) new_line;
if (recurse_flag) {
o = child(o);
@push lt_value; @push listing_together; @push listing_size;
@push c_iterator;
c_iterator = ObjectTreeIterator;
lt_value = 0; listing_together = 0; listing_size = 0;
WriteListR(o, depth+1, true);
@pull c_iterator;
@pull listing_size; @pull listing_together; @pull lt_value;
if (c_style & TERSE_BIT) print ")";
}
];
-) instead of "Write After Entry" in "ListWriter.i6t".
[This is a simplified copy of the list-writing code for a single group. The argument should be a description of a known subclass, like "ever-seen impets".]
To say group-list (desc - description of things): (- WriteSoloClassGroup({desc}); -).
Include (-
[ WriteSoloClassGroup desc obj ix;
obj = desc(-2);
if (obj == nothing) {
print "nothing";
return;
}
@push capitalize_class_group; @push listing_size; @push c_style;
listing_size = desc(-3);
c_style = 0;
capitalize_class_group = false;
BeginActivity(GROUPING_TOGETHER_ACT, obj);
if (ForActivity(GROUPING_TOGETHER_ACT, obj)) {
}
else {
obj = nothing;
for (ix=0 : ix<listing_size : ix++) {
obj = desc(-2, obj, ix);
if (ix) {
if (listing_size == 2)
print " and ";
else if (ix+1 == listing_size)
print ", and ";
else
print ", ";
}
print (name) obj;
give obj workflag;
}
}
EndActivity(GROUPING_TOGETHER_ACT, obj);
@pull c_style; @pull listing_size; @pull capitalize_class_group;
];
-).
[ObjectTreeCoalesce fix -- see Mantis bug 1913.]
Include (-
[ ObjectTreeCoalesce obj memb lt later;
#Ifdef DBLW; print "^^Sorting out: "; DiagnoseSortList(obj); #Endif;
.StartAgain;
memb = obj;
while (memb~=nothing) {
! Find the next object in a list_together run.
lt = memb.list_together;
if (lt == 0) {
memb = sibling(memb);
continue;
}
! Find first object after the contiguous run with this list_together value:
for (memb=sibling(memb): (memb) && (memb.list_together == lt): memb = sibling(memb)) ;
! If the contiguous run extends to end of list, the list is now perfect:
if (memb == 0) {
return obj;
}
! And otherwise we look to see if any future entries belong in the run:
for (later=sibling(memb): later: later=sibling(later)) {
if (later.list_together == lt) {
! Yes, they do: so we perform a regrouping of the list and start again:
obj = GroupChildren(parent(obj), list_together, lt);
#Ifdef DBLW; print "^^Sorted to: "; DiagnoseSortList(obj); #Endif;
jump StartAgain;
}
}
! No, that run is complete. Continue with the element that followed the run.
}
return obj;
];
#Ifdef DBLW;
[ DiagnoseSortList obj memb;
for (memb=child(obj): memb~=nothing: memb=sibling(memb)) print memb, " --> "; new_line;
];
#Endif;
-) instead of "Coalesce Object Tree" in "ListWriter.i6t".
Section - UI Go-To Events
Include (-
[ HandleGlkEvent ev ischar args val;
if (ischar == 0 && ev-->0 == $80002200) {
val = ev-->2;
glk_cancel_line_event(gg_mainwin, gg_event);
VM_PrintToBuffer(buffer, INPUT_BUFFER_LEN-WORDSIZE, PrintVisitNum, val);
return 2;
}
return 0;
];
[ PrintVisitNum val;
print "-VISIT-NUM ", val;
];
-) before "Stubs" in "Glulx.i6t".
Section - Library Deletions
Include (- -) instead of "Procedural Rule Changes" in "Rulebooks.i6t";
Include (-
[ UpdateActionBitmap; ]; ! Not used in this game
-) instead of "Actions Bitmap" in "Actions.i6t";
[I will be scrubbing the action_bitmap property from object definitions in the final build. But I'm nervous about it not existing as a property at all.]
Include (- with action_bitmap 1 -) when defining the Abstraction Layer.
Section - Extra Attributes
Include (-
{-call:Properties::alias_translations}
{-call:Properties::Implementation::OfObjects::compile_attributes}
{-array:Properties::Implementation::OfObjects::property_metadata}
Constant attributed_property_offsets_SIZE 56; ! Not 48!
Array attributed_property_offsets --> attributed_property_offsets_SIZE;
Constant valued_property_offsets_SIZE (100 + {-value:NUMBER_CREATED(property)} + INDIV_PROP_START-48);
Array valued_property_offsets --> valued_property_offsets_SIZE;
{-routine:Properties::Implementation::OfObjects::CreatePropertyOffsets}
-) instead of "Properties" in "Output.i6t".
Include (-
! These attributes are defined after the 47 that I7 knows about. We can define up to eight, since Glulx really allows 56.
Attribute attr_extra_metallic;
Attribute attr_extra_glassy;
Attribute attr_extra_mineralish;
Attribute attr_extra_readable;
[ CheckAttrExtraMetallic obj; return (obj has attr_extra_metallic); ];
[ CheckAttrExtraGlassy obj; return (obj has attr_extra_glassy); ];
[ CheckAttrExtraMineralish obj; return (obj has attr_extra_mineralish); ];
[ CheckAttrExtraReadable obj; return (obj has attr_extra_readable); ];
-) after "Properties" in "Output.i6t".
Section - Reaching Component Rules
Reaching component rules is an object-based rulebook.
Reaching component rules have outcomes allow access (success) and deny access (failure).
The access to parts rule is listed in the accessibility rulebook.
The access to parts rule translates into I6 as "AccessToPartsRule".
Include (-
[ AccessToPartsRule o p res;
!p = touch_persona;
!if (p == 0) p = actor;
o = untouchable_object;
while (o && (o provides component_parent) && (o.component_parent)) {
p = o.component_parent;
@push self;
self = o;
res = (ProcessRulebook( (+ Reaching component rules +), p) && RulebookFailed());
@pull self;
if (res)
rtrue;
o = p;
}
rfalse;
];
-).
Section - Altered Parser Errors
Rule for printing a parser error when the latest parser error is the I beg your pardon error:
[Can't tutor a node here, because we won't recycle to before-reading-command.]
if tutorial-display is true:
invoke tutor-blank-command;
do nothing.
To say current-pronoun-word: (- print (address) pronoun_word; -).
Rule for printing a parser error when the latest parser error is the not sure what it refers to error:
say "[parsermsg]I'm not sure what '[current-pronoun-word]' refers to[period]";
say "[/parsermsg][br]"
Rule for printing a parser error when the latest parser error is the not a verb I recognise error:
tutor tut-invalid-verb;
say "[parsermsg]That's not an action I understand[period]";
if tut-initial is open:
say " For right now, type [excmd]LOOK[/excmd] or [excmd]LOOK AROUND[/excmd][period]";
else if tutorial-phase is 1:
say " Common actions include [excmd]EXAMINE[/excmd] ([excmd]X[/excmd]), [excmd]TAKE[/excmd], and [excmd]DROP[/excmd]. Type [excmd]LOOK[/excmd] ([excmd]L[/excmd]) to review your surroundings[period]";
say "[/parsermsg][br]"
To say you-can't-see-any-such-thing:
if current-tense is:
-- present-tense: say "You can't see any such thing.";
-- past-tense: say "You couldn't see any such thing.";
-- perfect-tense: say "You cannot see any such thing.";
-- future-tense: say "You will not see any such thing."
Rule for printing a parser error when the latest parser error is the can't see any such thing error:
say you-can't-see-any-such-thing;
To say don't-know-tense:
if current-tense is:
-- present-tense: say "don't know";
-- past-tense: say "did not know";
-- perfect-tense: say "have not learned";
-- future-tense: say "will not know"
Rule for printing a parser error when the latest parser error is the noun did not make sense in that context error:
if the action-to-be is:
-- the inspecting it with action: say you-can't-see-any-such-thing;
-- the examining action: say you-can't-see-any-such-thing;
-- the recalling action: say "Nothing [if current-tense is present-tense]comes[else if current-tense is past-tense]came[else if current-tense is perfect-tense]has come[else if current-tense is future-tense]will come[else]comes[end if] to mind.";
-- the invoking action: say "You [don't-know-tense] any such formula.";
-- the performing action: say "You [don't-know-tense] any such ritual.";
-- the visiting action: say "You [don't-know-tense] any such location.";
-- the creating action: say "You [don't-know-tense] what that might be.";
-- otherwise: say "That noun did not make sense in this context."
Rule for printing a parser error when the latest parser error is the can't see it at the moment error and the pronoun reference object is a formula:
[separate case for formula-relevant actions, saying "you no longer recall..."? I'm not sure what fires this error, anyhow. (In I6 I think it was "x it" when "it" has been yanked away.)]
say "[The pronoun reference object] exists only in your mind."
Rule for printing a parser error when the latest parser error is the can't use multiple objects error:
[We'd like to catch "touch X and Y" and suggest "try touching X *to* Y". This is difficult. The action-to-be gets stuck on tapping-it-on even if the player just types "touch all", because it's the last grammar line. We work around this by picking the *first* grammar line -- usually better -- but either way we've lost the distinction.]
let AC be the initial action match for verb-word default action-to-be;
if AC is:
-- dropping action:
say you-can't-see-any-such-thing;
stop;
-- recalling-all action:
say "You can't use multiple terms that way. [parsermsg]Try just [excmd]RECALL[/excmd].[/parsermsg][br]";
stop;
-- vague-invoking action:
say "You can't use multiple terms that way.";
stop;
-- vague-entering action:
now AC is the entering action; [and continue...]
-- brush-rubbing action:
now AC is the rubbing action; [and continue...]
say "You can't use multiple objects that way";
let O be the first match-list item;
if O is nothing or the number of match-list items is greater than 3:
say ". [parsermsg]Try [AC with direct object namefake-just-one-thing-object].[/parsermsg][br]";
else:
say ". [parsermsg]Try [AC with direct object O].[/parsermsg][br]"
Rule for printing a parser error when the latest parser error is the only understood as far as error:
say parsermsg;
display the alternate only-understood error;
say /parsermsg;
say line break.
To display the alternate only-understood error: (- Alt_Only_Understood_Rule(); -).
Include (-
[ Alt_Only_Understood_Rule m ix addr len;
print "I understood the command ~";
for (ix=1: ix < wn_at_upto_pe-1 && ix <= num_words; ix++) {
if (ix ~= 1) print " ";
addr = WordAddress(ix);
len = WordLength(ix);
while (len) {
print (char) addr->0;
addr++; len--;
}
}
if (parse-->1 == 'look' or 'l//') {
addr = (+ excmding text +)-->1;
print "~, but not the following words. To look more closely at something, try ";
addr("LOOK AT OBJECT");
print " or ";
addr("EXAMINE OBJECT");
print ". You can also use the abbreviation ";
addr("X OBJECT");
print ".";
return;
}
print "~ (that is, ";
for (m=0 : m<32 : m++) pattern-->m = pattern2-->m;
pcount = pcount2;
PrintCommand(0);
print "); but not the word";
if (wn_at_upto_pe-1 ~= num_words) print "s";
print " ~";
for (ix=wn_at_upto_pe-1 : ix <= num_words; ix++) {
if (ix ~= wn_at_upto_pe-1) print " ";
addr = WordAddress(ix);
len = WordLength(ix);
while (len) {
print (char) addr->0;
addr++; len--;
}
}
print "~ at the end.";
];
-).
Section - Fast Iterating Through Contents
Include (-
Global rawloop_temp;
! Wrapper for sibling() which is safe to pass nothing to.
[ sibling_or_nothing obj;
if (~~obj) return nothing;
return sibling(obj);
];
-) after "Global Variables" in "Output.i6t".
[This uses a global variable, so it cannot be nested.]
To repeat with (loopvar - nonexisting object variable) in raw contents of (O - object) begin -- end: (-
for ({loopvar} = child({O}), rawloop_temp = sibling_or_nothing({loopvar})
: {loopvar}
: {loopvar} = rawloop_temp, rawloop_temp = sibling_or_nothing({loopvar}))
-).
To decide what number is the raw contents count of (O - object): (- children({O}) -).
[This ignores incorporation relations, wearing relations, and all that modern world-model jazz. Only use it for non-things (formulas, etc).]
To raw-remove (O - object) from play: (- remove({O}); -).
Section - Static Listing Contents
The initially listing contents rules are a rulebook.
When play begins (this is the initially list contents rule):
follow the initially listing contents rules.
To initially group (OS - description of objects) together: (- InitiallyGroupTogether({OS}, {-list-together}); -).
Include (-
! We've commented out the code in WriteListFrom that clears the list_together flag. Instead we do it all at startup time, here.
[ InitiallyGroupTogether desc func obj;
obj = nothing;
while (obj = desc(-2, obj)) {
obj.list_together = func;
}
];
-).
To say a (O - object) roomily: (- WriteListSingleton({O}, ENGLISH_BIT+PARTINV_BIT); -).
To say A (O - object) roomily: (- WriteListSingleton({O}, ENGLISH_BIT+CFIRSTART_BIT+PARTINV_BIT); -).
To say a list of (OS - description of objects) *in (parent - object):
(- @push subst__v;
objectloop (subst__v in {parent}) if ({-bind-variable:OS})
give subst__v workflag2; else give subst__v ~workflag2;
WriteListOfMarkedContentsObjects(ENGLISH_BIT, {parent});
@pull subst__v; -).
To say a list of (OS - description of objects) *in (parent - object) roomily:
(- @push subst__v;
objectloop (subst__v in {parent}) if ({-bind-variable:OS})
give subst__v workflag2; else give subst__v ~workflag2;
WriteListOfMarkedContentsObjects(ENGLISH_BIT+PARTINV_BIT, {parent});
@pull subst__v; -).
To say A list of (OS - description of objects) *in (parent - object):
(- @push subst__v;
objectloop (subst__v in {parent}) if ({-bind-variable:OS})
give subst__v workflag2; else give subst__v ~workflag2;
WriteListOfMarkedContentsObjects(ENGLISH_BIT+CFIRSTART_BIT, {parent});
@pull subst__v; -).
To say A list of (OS - description of objects) *in (parent - object) roomily:
(- @push subst__v;
objectloop (subst__v in {parent}) if ({-bind-variable:OS})
give subst__v workflag2; else give subst__v ~workflag2;
WriteListOfMarkedContentsObjects(ENGLISH_BIT+CFIRSTART_BIT+PARTINV_BIT, {parent});
@pull subst__v; -).
To say list of (OS - description of objects) *in (parent - object):
(- @push subst__v;
objectloop (subst__v in {parent}) if ({-bind-variable:OS})
give subst__v workflag2; else give subst__v ~workflag2;
WriteListOfMarkedContentsObjects(ENGLISH_BIT+NOARTICLE_BIT, {parent});
@pull subst__v; -).
To say the list of (OS - description of objects) *in (parent - object):
(- @push subst__v;
objectloop (subst__v in {parent}) if ({-bind-variable:OS})
give subst__v workflag2; else give subst__v ~workflag2;
WriteListOfMarkedContentsObjects(ENGLISH_BIT+DEFART_BIT, {parent});
@pull subst__v; -).
To say the list of (OS - description of objects) *in (parent - object) roomily:
(- @push subst__v;
objectloop (subst__v in {parent}) if ({-bind-variable:OS})
give subst__v workflag2; else give subst__v ~workflag2;
WriteListOfMarkedContentsObjects(ENGLISH_BIT+DEFART_BIT+PARTINV_BIT, {parent});
@pull subst__v; -).
To say The list of (OS - description of objects) *in (parent - object):
(- @push subst__v;
objectloop (subst__v in {parent}) if ({-bind-variable:OS})
give subst__v workflag2; else give subst__v ~workflag2;
WriteListOfMarkedContentsObjects(ENGLISH_BIT+DEFART_BIT+CFIRSTART_BIT, {parent});
@pull subst__v; -).
To say is-are a list of (OS - description of objects) *in (parent - object):
(- @push subst__v;
objectloop (subst__v in {parent}) if ({-bind-variable:OS})
give subst__v workflag2; else give subst__v ~workflag2;
WriteListOfMarkedContentsObjects(ENGLISH_BIT+ISARE_BIT, {parent});
@pull subst__v; -).
To say is-are a list of (OS - description of objects) *in (parent - object) roomily:
(- @push subst__v;
objectloop (subst__v in {parent}) if ({-bind-variable:OS})
give subst__v workflag2; else give subst__v ~workflag2;
WriteListOfMarkedContentsObjects(ENGLISH_BIT+ISARE_BIT+PARTINV_BIT, {parent});
@pull subst__v; -).
To say is-are list of (OS - description of objects) *in (parent - object):
(- @push subst__v;
objectloop (subst__v in {parent}) if ({-bind-variable:OS})
give subst__v workflag2; else give subst__v ~workflag2;
WriteListOfMarkedContentsObjects(ENGLISH_BIT+ISARE_BIT+NOARTICLE_BIT, {parent});
@pull subst__v; -).
To say is-are the list of (OS - description of objects) *in (parent - object):
(- @push subst__v;
objectloop (subst__v in {parent}) if ({-bind-variable:OS})
give subst__v workflag2; else give subst__v ~workflag2;
WriteListOfMarkedContentsObjects(ENGLISH_BIT+DEFART_BIT+ISARE_BIT, {parent});
@pull subst__v; -).
Include (-
! Sort the first N rows of a table, rather than the whole thing. The rest
! of the table is untouched. Blank rows are sorted down to position N (not
! to the very end).
[ TableSortPartial tab rows col dir test_flag algorithm i j k f;
for (i=1:i<=tab-->0:i++) {
j = tab-->i; ! Address of column table
if ((j-->1) & TB_COLUMN_DONTSORTME)
return RunTimeProblem(RTP_TABLE_CANTSORT, tab);
}
if (col >= 100) col=TableFindCol(tab, col, false);
k = rows; ! Not the entire table
k = TableMoveBlanksToBack(tab, 1, k);
if (test_flag) {
print "After moving blanks to back:^"; TableColumnDebug(tab, col);
}
SetSortDomain(TableSwapRows, TableCompareRows);
SortArray(tab, col, dir, k, test_flag, algorithm);
if (test_flag) {
print "Final state:^"; TableColumnDebug(tab, col);
}
];
-) after "Sort" in "Tables.i6t".
To sort (T - table name) up to row (N - number) in (TC - table column) order
(documented at ph_sortcolumn):
(- TableSortPartial({T}, {N}, {TC}, 1); -).
[We have to clear these flags for every thing. It's worth having a routine that skips I7's usual SetEitherOrProperty() mechanism and all its safety checks.]
To rapidly set all things not mentioned: (- OptimizedAllThingsUnsetMentioned(); -).
To rapidly set all things not marked for listing: (- OptimizedAllThingsUnsetWorkflag(); -).
Include (-
[ OptimizedAllThingsUnsetMentioned obj;
for (obj=IK2_First: obj: obj=obj.IK2_Link) {
give obj ~mentioned;
}
];
[ OptimizedAllThingsUnsetWorkflag obj;
for (obj=IK2_First: obj: obj=obj.IK2_Link) {
give obj ~workflag;
}
];
-).
[We never want to search (or sort) through the entire Table of Locale Priorities, so we manually keep track of the number of "live" rows. We'll also avoid use of the I7 notion of blank rows. Unused rows will be marked by "nothing" in the object column.]
The locale-table-count is a number that varies.
[This replacement phrase is heavily optimized. It behaves the same as the standard version, except that deleted rows get "nothing" in the object column instead of being marked blank.]
To set the/-- locale priority of (O - an object) to (N - a number):
if O is a thing:
if N <= 0:
now O is mentioned;
[search the active part of the table for O; also note the first null row]
let rownum be 0;
let blanknum be 0;
repeat with I running from 1 to locale-table-count:
let ent be the notable-object in row I of the Table of Locale Priorities;
if ent is nothing:
if blanknum is 0:
now blanknum is I;
next;
if ent is O:
now rownum is I;
break;
if rownum > 0: [found it]
if N > 0:
[change the existing row]
choose row rownum in the Table of Locale Priorities;
now the locale description priority entry is N;
else:
[delete the existing row, by putting in "nothing".]
choose row rownum in the Table of Locale Priorities;
now the notable-object entry is nothing;
now the locale description priority entry is 999;
otherwise: [didn't find it]
if N > 0:
if blanknum is 0:
[add a new row]
increment locale-table-count;
choose row locale-table-count in the Table of Locale Priorities;
now the notable-object entry is O;
now the locale description priority entry is N;
else:
[use the found null row]
choose row blanknum in the Table of Locale Priorities;
now the notable-object entry is O;
now the locale description priority entry is N.
The optimized initialise locale description rule is listed instead of the initialise locale description rule in the before printing the locale description rulebook.
This is the optimized initialise locale description rule:
now the locale paragraph count is 0;
rapidly set all things not mentioned; [loops through all things]
[Mark the table as empty (without blanking every single row)]
now the locale-table-count is zero.
The optimized interesting locale paragraphs rule is listed instead of the interesting locale paragraphs rule in the for printing the locale description rulebook.
This is the optimized interesting locale paragraphs rule:
let the domain be the parameter-object;
sort the Table of Locale Priorities up to row locale-table-count in locale description priority order;
repeat with I running from 1 to locale-table-count:
let O be the notable-object in row I of the Table of Locale Priorities;
if O is not nothing:
carry out the printing a locale paragraph about activity with O;
continue the activity.
The optimized you-can-also-see rule is listed instead of the you-can-also-see rule in the for printing the locale description rulebook.
This is the optimized you-can-also-see rule:
let the domain be the parameter-object;
let the mentionable count be 0;
let the marked count be 0;
rapidly set all things not marked for listing; [loops through all things]
repeat with I running from 1 to locale-table-count:
let O be the notable-object in row I of the Table of Locale Priorities;
if O is not nothing:
let N be the locale description priority in row I of the Table of Locale Priorities;
[say "[O] - [N].";]
if N is greater than 0 and O is not mentioned:
now O is marked for listing;
increment the marked count;
increase the mentionable count by 1;
if the mentionable count is greater than 0:
[note that mentioned things have not been marked for listing]
begin the listing nondescript items activity with the domain;
if the marked count is 0:
abandon the listing nondescript items activity with the domain;
otherwise:
if handling the listing nondescript items activity:
if the domain is a room:
if the domain is the location, say "You ";
otherwise say "In [the domain] you ";
otherwise if the domain is a supporter:
say "On [the domain] you ";
otherwise if the domain is an animal:
say "On [the domain] you ";
otherwise:
say "In [the domain] you ";
say "can [if the locale paragraph count is greater than 0]also [end if]see ";
let the common holder be nothing;
let contents form of list be true;
repeat with I running from 1 to locale-table-count:
let list item be the notable-object in row I of the Table of Locale Priorities;
if list item is nothing or list item is not marked for listing:
next;
if the holder of the list item is not the common holder:
if the common holder is nothing,
now the common holder is the holder of the list item;
otherwise now contents form of list is false;
if the list item is mentioned, now the list item is not marked for listing;
filter list recursion to unmentioned things;
if contents form of list is true and the common holder is not nothing,
list the contents of the common holder, as a sentence, including contents,
giving brief inventory information, tersely, not listing
concealed items, listing marked items only;
otherwise say "[a list of marked for listing things including contents]"; [loops through all things]
if the domain is the location, say " here";
say ".[paragraph break]";
unfilter list recursion;
end the listing nondescript items activity with the domain;
continue the activity.
To begin cheap list for (N - number): (- cheaplist_count = 0; cheaplist_total = {N}; @push subst__v; -).
To end cheap list: (- cheaplist_count = 0; cheaplist_total = 0; @pull subst__v; -).
To say cheap list (T - object) with (M - text): (- cheaplist_entry({T}, {M}); -).
Include (-
Global cheaplist_count = 0;
Global cheaplist_total = 0;
[ cheaplist_entry obj text;
subst__v = obj;
if (cheaplist_count) {
if (cheaplist_total == 2)
print " and ";
else if (cheaplist_count + 1 == cheaplist_total)
print ", and ";
else
print ", ";
}
print (PrintText) text;
cheaplist_count++;
];
-) before "Parser.i6t".
Section - Miscellany of Doors
A glass-window is a kind of door.
A glass-window is usually open.
A glass-window is usually unopenable.
A glass-window is usually glassy.
A glass-window is usually scenery.
The printed name of a glass-window is usually "window".
The description of a glass-window is usually "A glass window."
Understand "locked", "sealed" as a door when the item described is locked.
Understand "open", "opened" as a door when the item described is open and the item described is not a glass-window.
Understand "closed" as a door when the item described is closed and the item described is not a glass-window.
The description of a door is usually "[The item described] is [open-closed item described]."
Section - Absent Doors
Definition: a door is absent rather than present if I6 routine "AssertDoorAbsent" makes it so (it is out of scope and unusable).
Include (-
[ AssertDoorAbsent door flag
addr rm1 rm2 dir1 dir2 off1 off2;
if (flag == -1) {
return (door has absent);
}
! door.found_in should be a list of two rooms, which is I7's normal arrangement
addr = door.&found_in;
if (addr == 0 || door.#found_in ~= 2*WORDSIZE)
"(BUG) Cannot activate/deactivate door: malformed found_in: ", (name) door;
rm1 = addr-->0;
rm2 = addr-->1;
@push location;
location = rm1;
dir1 = door.door_dir();
location = rm2;
dir2 = door.door_dir();
@pull location;
if (~~(dir1 ofclass (+ direction +) && dir2 ofclass (+ direction +) ))
"(BUG) Cannot activate/deactivate door: directions not found: ", (name) door;
off1 = ((rm1.IK1_Count)*No_Directions + dir1.IK3_Count);
off2 = ((rm2.IK1_Count)*No_Directions + dir2.IK3_Count);
if (flag) {
if (door hasnt absent) {
!print "(DEBUG) absentify ", (name) door, "^";
SignalMapChange();
if (Map_Storage-->off1 == door)
Map_Storage-->off1 = 0;
else
print "(BUG) Map_Storage from door does not match^";
if (Map_Storage-->off2 == door)
Map_Storage-->off2 = 0;
else
print "(BUG) Map_Storage from door does not match^";
give door absent;
remove door;
}
}
else {
if (door has absent) {
!print "(DEBUG) presentify ", (name) door, "^";
SignalMapChange();
if (Map_Storage-->off1 == 0)
Map_Storage-->off1 = door;
else
print "(BUG) Map_Storage from door does not match^";
if (Map_Storage-->off2 == 0)
Map_Storage-->off2 = door;
else
print "(BUG) Map_Storage from door does not match^";
give door ~absent;
if (rm1 == real_location || rm2 == real_location)
move door to real_location;
else
remove door;
}
}
];
-).
Section - Tenses
[The endgame involves some tense-shifting. We do *not* try to tense-enable all of the game text! Only a few generic messages and errors that can show up in the endgame.]
Tense-type is a kind of value. The tense-types are present-tense, past-tense, perfect-tense, and future-tense.
The current-tense is a tense-type that varies. The current-tense is present-tense.
To say you're-not-sure:
if current-tense is:
-- present-tense: say "You're not sure.";
-- past-tense: say "You weren't sure.";
-- perfect-tense: say "You aren't sure.";
-- future-tense: say "You won't be sure."
Section - Early Type Declarations
The no-thing is a thing.
[These types should cover everything the player can pick up and move -- everything which can be "handled".]
A takeable-thing is a kind of thing.
A takeable-supporter is a kind of supporter. A takeable-supporter is always portable.
[There are no takeable-containers.]
Definition: a thing is takeable rather than non-takeable if it is a takeable-thing or it is a takeable-supporter.
Room-atmosphere is a kind of value.
The room-atmospheres are normal-atm, fire-atm, water-atm, vacuum-atm.
A room has a room-atmosphere called the atmosphere.
Definition: a room is aroma-proof if the atmosphere of it is not normal-atm.
Definition: a room is airless if the atmosphere of it is water-atm or the atmosphere of it is vacuum-atm.
An inscribable is a kind of takeable-thing.
Descriptor-type is a kind of value.
The descriptor-types are no-descriptor, brass-descriptor, steel-descriptor, bronze-descriptor, glass-descriptor, earthy-descriptor, wood-descriptor, spiritual-descriptor.
Definition: a thing is descriptor-compatible if it provides the property descriptor-type.
The verb to descriptor-match (it descriptor-matches, they descriptor-match, it is descriptor-matching) implies the descriptor-type property.
A inscribable has a descriptor-type. The descriptor-type of an inscribable is usually no-descriptor.
[Always use these adjectives, rather than "if nothing is in..."]
Definition: a container is empty rather than non-empty if the first thing held by it is nothing.
Definition: a supporter is empty rather than non-empty if the first thing held by it is nothing.
[Used to refer to a recalled item, where we want to be conservative about dynamic name-changes.]
A thing has some text called the remote-name. The remote-name of a thing is usually "the [item described]".
The remote-name of the player is "yourself".
[Applies to mass nouns, anything with "quantity of..." etc. Used in sentences like "You need more ..." as opposed to "You need another ..."]
A thing can be mass-named.
A thing can be alight. [Relevant to the fire daemon, but we define it early to catch an attribute slot.]
A thing can be metallic. [Gensaturation almost works on it.]
A thing can be glassy. [Glass-pass almost works on it.]
A thing can be mineralish. [The solvents are customized for every stone object.]
A thing can be symbolish. [An object too fancy for the word of essential nature.]
[Use direct I6 attributes for some read-only binary properties. We need the extra definitions because the default attribute test goes through GetEitherOrProperty, and trips over some type-checking. (The attributed_property_offsets table isn't valid for these extras.)]
The metallic property translates into I6 as "attr_extra_metallic".
Definition: an object is metallic if I6 routine "CheckAttrExtraMetallic" says so (hack).
The glassy property translates into I6 as "attr_extra_glassy".
Definition: an object is glassy if I6 routine "CheckAttrExtraGlassy" says so (hack).
The mineralish property translates into I6 as "attr_extra_mineralish".
Definition: an object is mineralish if I6 routine "CheckAttrExtraMineralish" says so (hack).
[Used to refer to a room in sentences.]
A room has some text called the refer-name. The refer-name of a room is usually "[the item described]".
A room has some text called the refer-preposition. The refer-preposition of a room is usually "in".
Understand "room" as a room.
A room-proxy is a kind of thing. A room-proxy is usually scenery.
Check getting off a room-proxy:
instead try exiting.
Check smelling a room-proxy:
instead try smelling the location.
Check inserting something into a room-proxy:
instead try dropping the noun.
Section - Utility Classes
A far-sight is a kind of thing.
A far-sight is usually scenery.
A far-sight has a text called the reach-reason. The reach-reason of a far-sight is usually "[The item described] is out of reach."
Instead of doing anything except examining or searching or entering to a far-sight (this is the far-sight out of reach rule):
if inspecting a far-sight with something:
continue the action;
if reading a readable far-sight:
continue the action;
instead say "[the reach-reason of the noun][line break]".
Check putting something on a far-sight:
instead try touching the second noun.
Check inserting something into a far-sight:
instead try touching the second noun.
Check tapping something on a far-sight:
instead try touching the second noun.
Check entering a far-sight:
[not caught by the Instead rule; can be customized separately.]
instead try touching the noun.
Check searching a far-sight:
[not caught by the Instead rule; can be customized separately.]
instead try touching the noun.
Section - Epistemology
Definition: a thing is ever-made-this-cycle rather than never-made-this-cycle if it is handled or it is on-stage. [This is only meant for created takeables (such as wire).]
A room can be visited-this-cycle or unvisited-this-cycle. A room is always unvisited-this-cycle.
A room can be recallable. [Rooms which can be explicitly visited/gone to from other rooms.]
A thing can be recallable. [Things that can be recalled from out of scope. All takeable things are recallable, but some scenery (important machines) are also recallable.]
A thing can be ever-seen. [Never reset; this marks what the player knows about. This is splashed around liberally -- everything whose name is printed, everything in the location and the player's inventory.]
A takeable-thing is usually recallable.
A takeable-supporter is usually recallable.
[### probably make the red and white amalgam wires non-recallable, so that they don't fluff up the "findable" namespace. Ditto all the amalgam file seals. Possibly the plain gold rod?]
[### more of a nuisance: objects like "rough diamond" / "perfect diamond", where the latter form keeps "rough" as a synonym. Which is good for normal interactions, but terrible for find/recall. Maybe we want a set of does-the-player-mean rules.]
Include (-
[ NOTE_OBJECT_ACQUISITIONS_R obj;
objectloop (obj in player) {
give obj moved ~concealed; ! "moved" is "handled"
give obj (+ ever-seen +);
! We don't need to worry about concealed things indirectly-contained in the player.
}
! We don't need to worry about RUCKSACK_CLASS either.
rfalse;
];
-) instead of "Note Object Acquisitions Rule" in "OrderOfPlay.i6t".
[Override the library's "set pronouns from..." phrase, though not the low-level PronounNotice() call.]
To set pronouns from (O - an object):
(- ExplicitPronounNotice({O}); -).
Include (-
[ ExplicitPronounNotice obj;
PronounNotice(obj);
give obj (+ ever-seen +);
];
-).
Before printing the name of a thing (called T) (this is the extended make named things mentioned rule):
now T is mentioned;
unless the current action is out-of-world:
now T is ever-seen.
The extended make named things mentioned rule is listed instead of the make named things mentioned rule in the before printing the name rulebook.
[The correct fix for Mantis bug 1368.]
The fixed offer items to writing a paragraph about rule is listed instead of the offer items to writing a paragraph about rule in the for printing a locale paragraph about rulebook.
For printing a locale paragraph about a thing (called the item) (this is the fixed offer items to writing a paragraph about rule):
if the item is not mentioned:
if a paragraph break is pending, say "[conditional paragraph break]";
carry out the writing a paragraph about activity with the item;
if a paragraph break is pending:
increase the locale paragraph count by 1;
now the item is mentioned;
say "[conditional paragraph break]";
continue the activity.
The last-visited-room is a room that varies. The last-visited-room is the Abstraction Layer.
Include (-
[ SilentlyConsiderLight;
lightflag = true; ! no true darkness (if there were true darkness, we'd have to pre-check new arrivals in the adjust light rule too!)
location = real_location; ! if ~~lightflag, location = thedark;
ProcessRulebook( (+ pre-check new arrival rule +) );
rfalse;
];
-) instead of "Silent Light Consideration" in "Light.i6t".
This is the pre-check new arrival rule:
if not in darkness and the location is a room:
if the location is not the last-visited-room:
now the last-visited-room is the location;
repeat with T in raw contents of the location:
now T is ever-seen;
carry out the room-visiting activity with the location;
now the location is visited-this-cycle.
Room-visiting something is an activity on rooms.
[The room will be "unvisited" ("unvisited-this-cycle") if this is the first trip (this cycle).]
Before room-visiting when goal-achieving:
increment the room-count of goalstate.
Definition: a thing is quick-visible if it is quick-visible-to the location.
To decide whether (T - thing) is quick-visible-to (R - room):
(- QuickVisibleTo({T}, {R}) -).
Include (-
[ QuickVisibleTo obj loc
next;
if (obj == nothing || loc == nothing)
rfalse;
if (obj ofclass (+ door +) ) {
print "(DEBUG) QuickVisibleTo does not work on doors.^";
rfalse;
}
if (obj ofclass (+ backdrop +) ) {
print "(DEBUG) QuickVisibleTo does not work on backdrops.^";
rfalse;
}
while (obj) {
next = obj.component_parent;
if (next) {
obj = next;
continue;
}
next = parent(obj);
if (~~next)
rfalse;
if (next == loc)
rtrue;
if (IsSeeThrough(next)) {
obj = next;
continue;
}
rfalse;
}
rfalse;
];
-).
Section - Abstract Buckets
The Abstraction Layer is a room. The description is "(BUG) This room only exists for things to be temporarily out of the game, but not off-stage."
[Decide whether a room value is outside the world (not a game room). Returns true for "nothing". Do not call this on things.] [This can't be a definition because we have to avoid type-checking. "nothing" never type-checks as any kind.]
To decide whether (R - object) is-room off-stagey: (- (RoomIsOffstage({R})) -).
To decide whether (R - object) is-not-room off-stagey: (- (~~RoomIsOffstage({R})) -).
Include (-
[ RoomIsOffstage rm;
if (rm == nothing)
rtrue;
if (rm == (+ Abstraction Layer +) )
rtrue;
rfalse;
];
-).
An abstraction-bucket is a kind of container.
An abstraction-bucket has some text called the short-description. The short-description of an abstraction-bucket is usually "(BUG)s".
An abstraction-bucket has some text called the short-description-multi. The short-description-multi of an abstraction-bucket is usually "(BUG)".
All abstraction-buckets are in the Abstraction Layer.
To sanity-check the empty buckets:
let total-buckets be the number of non-empty abstraction-buckets;
if total-buckets is not zero:
say "(BUG) [total-buckets] buckets were left nonempty ([list of non-empty abstraction-buckets])."
To recite the buckets, omitting final period:
let total-buckets be the number of non-empty abstraction-buckets;
if total-buckets is zero:
stop;
let count be zero;
repeat with bucket running through non-empty abstraction-buckets:
if count is zero:
say ", ";
else:
say "; ";
list the contents of bucket, tersely, as a sentence, using the definite article;
say " [if the number of things in bucket is one][short-description of bucket][else][short-description-multi of bucket][end if]";
increment count;
unless omitting final period:
say "."
Section - Better Lock-Matching
Check an actor unlocking something with (this is the better can't unlock without the correct key rule):
unless the holder of the second noun is the actor and lock the noun really matches key the second noun:
instead say "[That-Those second noun] [doesn't-don't second noun] seem to fit the lock."
Check an actor locking something with (this is the better can't lock without the correct key rule):
unless the holder of the second noun is the actor and lock the noun really matches key the second noun:
instead say "[That-Those second noun] [doesn't-don't second noun] seem to fit the lock."
The better can't unlock without the correct key rule is listed instead of the can't unlock without the correct key rule in the check unlocking it with rulebook.
The better can't lock without the correct key rule is listed instead of the can't lock without the correct key rule in the check locking it with rulebook.
The key-param is an object that varies.
The lock-param is an object that varies.
The lock-param variable translates into I6 as "parameter_object".
To decide whether lock (L - object) really matches key (K - thing):
now the key-param is K;
[lock-param is the normal parameter variable, so we don't need to set it.]
follow the lock-matching rules for L;
if rule failed:
decide no;
else:
decide yes.
Lock-matching is an object-based rulebook.
The last lock-matching rule when lock-param provides the property matching key (this is the original property-based lock-matching rule):
let T be the matching key of lock-param;
if T is not nothing:
if key-param is T:
rule succeeds;
else:
rule fails.
The last lock-matching rule (this is the give-up lock-matching rule):
rule fails.
Section - The Thing-Taken-From
The taking action has an object called the thing-taken-from.
Carry out an actor taking (this is the better taking rule):
[I suspect this is not completely reliable. (Components, maybe some check-taking rules that bypass the standard action.) But it's good enough for report rules.]
now the thing-taken-from is the holder of the noun;
now the actor carries the noun.
The better taking rule is listed instead of the standard taking rule in the carry out taking rulebook.
Section - Better Implicit Taking
Definition: a thing is sessile if it is scenery or it is fixed in place or it is the player.
Definition: a thing is sessile-besides-player if it is scenery or it is fixed in place.
To decide whether interrupted carrying out the (A - activity on nothing) activity:
(- CarryOutActivity({A}) -).
To decide whether interrupted carrying out the (A - activity on value of kind K) activity with (val - K):
(- CarryOutActivity({A}, {val}) -).
Check an actor inserting something into (this is the better can't insert what's not held rule):
if the actor is carrying the noun, continue the action;
if the actor is wearing the noun, continue the action;
if interrupted carrying out the implicitly taking activity with the noun:
stop the action;
issue miscellaneous library message number 26 for the noun;
silently try the actor taking the noun;
if the actor is carrying the noun:
now the noun is handled;
continue the action;
stop the action.
Check an actor putting something on (this is the better can't put what's not held rule):
if the actor is carrying the noun, continue the action;
if the actor is wearing the noun, continue the action;
if interrupted carrying out the implicitly taking activity with the noun:
stop the action;
issue miscellaneous library message number 26 for the noun;
silently try the actor taking the noun;
if the actor is carrying the noun:
now the noun is handled;
continue the action;
stop the action.
The better can't insert what's not held rule is listed instead of the can't insert what's not held rule in the check inserting it into rulebook.
The better can't put what's not held rule is listed instead of the can't put what's not held rule in the check putting it on rulebook.
Rule for implicitly taking the player (this is the don't implicitly take myself rule):
say "You can't haul yourself around like that."
Check eating something not sessile (this is the can't eat what's not held rule):
if the actor is carrying the noun, continue the action;
if the actor is wearing the noun, continue the action;
if interrupted carrying out the implicitly taking activity with the noun:
stop the action;
issue miscellaneous library message number 26 for the noun;
silently try the actor taking the noun;
if the actor is carrying the noun, continue the action;
stop the action.
The can't wave what's not held rule is not listed in any rulebook.
First check waving something not sessile (this is the better can't wave what's not held rule):
if the actor is carrying the noun, continue the action;
if interrupted carrying out the implicitly taking activity with the noun:
stop the action;
issue miscellaneous library message number 26 for the noun;
silently try the actor taking the noun;
if the actor is carrying the noun, continue the action;
stop the action.
First check shaking something not sessile (this is the can't shake what's not held rule):
if the actor is carrying the noun, continue the action;
if interrupted carrying out the implicitly taking activity with the noun:
stop the action;
issue miscellaneous library message number 26 for the noun;
silently try the actor taking the noun;
if the actor is carrying the noun, continue the action;
stop the action.
First check inspecting something with something not sessile (this is the can't inspect with what's not held rule):
if the actor is carrying the second noun, continue the action;
if interrupted carrying out the implicitly taking activity with the second noun:
stop the action;
issue miscellaneous library message number 26 for the second noun;
silently try the actor taking the second noun;
if the actor is carrying the second noun, continue the action;
stop the action.
Check burning it with (this is the can't burn with what's not held rule):
if the noun is sessile-besides-player and the second noun is sessile:
instead say "You cannot move them together.";
if the second noun is sessile:
if the actor is carrying the noun, continue the action;
if the actor is the noun, continue the action;
if interrupted carrying out the implicitly taking activity with the noun:
stop the action;
issue miscellaneous library message number 26 for the noun;
silently try the actor taking the noun;
if the actor is carrying the noun, continue the action;
stop the action;
if the actor is not carrying the noun and the actor is not carrying the second noun:
if the actor is the noun, continue the action;
if interrupted carrying out the implicitly taking activity with the second noun:
stop the action;
issue miscellaneous library message number 26 for the second noun;
silently try the actor taking the second noun;
if the actor is carrying the second noun, continue the action;
stop the action.
Check taking the paten when something is on the paten:
let N be the number of things on the paten;
if N is greater than one:
instead say "The paten has too many things on it to be moved.";
let T be the first thing held by the paten;
if interrupted carrying out the implicitly taking activity with T:
stop the action;
say "(first taking [the T] from the paten)";
silently try the actor taking T;
if something is on the paten:
stop the action.
Check taking the labyrinth-tile when something is on the labyrinth-tile:
let N be the number of things on the labyrinth-tile;
if N is greater than one:
instead say "The tile has too many things on it to be moved.";
let T be the first thing held by the labyrinth-tile;
if interrupted carrying out the implicitly taking activity with T:
stop the action;
say "(first taking [the T] from the tile)";
silently try the actor taking T;
if something is on the labyrinth-tile:
stop the action.
Check taking a clay-mold when something is on the noun:
let N be the number of things on the noun;
if N is greater than one:
instead say "The mold disk has too many things on it to be moved.";
let T be the first thing held by the noun;
if T is a low-melting-seal metal-seal and T matches the noun:
if the noun is in the kiln:
say "You lift [the noun], and blow on the [smetal of T] until it cools a bit. Then you";
else:
say "You lift [the noun], and";
now the player carries T;
now the player carries the noun;
instead say " dump the seal out into your palm. It's a [first time]perfect -- well, it's a [only]pretty good impression of the [file of T] File badge.";
if interrupted carrying out the implicitly taking activity with T:
stop the action;
say "(first taking [the T] from the clay mold)";
silently try the actor taking T;
if something is on the noun:
stop the action.
Chapter - Seeking Beyond the Boundary
Section - Goal Basics
A goal is a kind of object.
A room-goal is a kind of goal. [A region of rooms, for goal-tracking purposes.]
An action-goal is a kind of goal. [Do something.]
An action-goal can be known or unknown. An action-goal is usually unknown. [Has the player read about it? If so, it's in known-rituals. Only meaningful for recallable goals.]
An action-goal can be ever-done. [Has the player done it? Or done a ritual which is close enough that the experience carries over? (Ever-done and recallable implies known.)]
An action-goal can be reentrant. [Can be on the goal stack more than once.]
An action-goal can be described or undescribed. An action-goal is usually described. [Listed when reciting the goal stack on failure.]
An action-goal can be recallable. [Actions which can be explicitly performed.]
An action-goal has some text called the short-description. The short-description of an action-goal is usually "do something".
An action-goal has some text called the description. The description of an action-goal is usually "(BUG) Undescribed action-goal."
An action-goal can be privately-named or publically-named. An action-goal is usually publically-named. [They are typable, in the "perform" grammar.]
Understand "ritual", "goal" as an action-goal.
A thing has an action-goal called the creation-action. The creation-action of a thing is usually impossible-goal.
The known-rituals is a container.
To mark (G - action-goal) as known: (- MarkActionGoalKnown({G}); -).
To mark (G - action-goal) as done: (- MarkActionGoalDone({G}); -).
Include (-
[ MarkActionGoalKnown goal;
if (goal == nothing || goal == (+ impossible-goal +)) {
print "(BUG) MarkActionGoalKnown(", (name) goal, ")!^";
return;
}
if (~~GetEitherOrProperty(goal, (+ recallable +) )) {
print "(BUG) MarkActionGoalKnown(", (name) goal, "), which is not recallable!^";
}
if (~~(goal in (+ known-rituals +) )) {
move goal to (+ known-rituals +);
}
SetEitherOrProperty(goal, (+ known +) );
#ifdef DEBUG;
if (goal_practice_flag) {
SetEitherOrProperty(goal, (+ ever-done +) );
}
#endif; ! DEBUG
];
[ MarkActionGoalDone goal;
if (goal == nothing || goal == (+ impossible-goal +)) {
print "(BUG) MarkActionGoalKnown(", (name) goal, ")!^";
return;
}
if (GetEitherOrProperty(goal, (+ recallable +) ) && ~~GetEitherOrProperty(goal, (+ known +) )) {
! For recallable goals, ensure they are thrown into the "known" bucket.
MarkActionGoalKnown(goal);
}
SetEitherOrProperty(goal, (+ ever-done +) );
#ifdef DEBUG_RITUAL;
! It's possible for a goal to be fulfilled several times in a turn, but let's only name it once.
if ((~~not_yet_in_play) && (~~barearray_contains(debugrituals_barearray, goal))) {
if (debugrituals_barearray-->1 < barearray_limit(debugrituals_barearray)) {
if (debugrituals_barearray-->1 < barearray_limit(debugrituals_barearray)-1)
barearray_append(debugrituals_barearray, goal);
else
barearray_append(debugrituals_barearray, "...too many to list...");
}
}
#endif; ! DEBUG_RITUAL
];
-).
No-zone is a room-goal. [Not eligible for goto-tracking; apologize. Used for in-between states like being underwater or lost.]
A room has a room-goal called the zone. The zone of a room is usually no-zone.
The verb to zone-inhabit (it zone-inhabits, they zone-inhabit, it is zone-inhabiting) implies the zone property.
Definition: a room is zoneless if the zone of it is no-zone.
A room has a room called the near-zone-room. The near-zone-room of a room is usually nothing. [Only meaningful for zoneless rooms.]
A room-goal has a room called the canon-room. The canon-room of a room-goal is usually nothing.
The impossible-goal is an action-goal. [Vague that's-impossible refusal.]
The short-description of impossible-goal is "achieve the impossible".
To decide what room-goal is the current zone:
decide on the zone of the location.
To decide what room-goal is the containing zone of (T - thing):
if T is off-stage:
decide on no-zone;
let R be the location of T;
if R is nothing:
decide on no-zone;
decide on the zone of R.
To decide what room is the canonical room of (G - room-goal):
if G is no-zone:
really decide on nothing;
let R be the canon-room of G;
if R is not nothing:
decide on R;
[We'll have to do this the slow way. (Can't use "if a room (called R) zone-inhabits G..." due to Mantis bug 1046.)]
repeat with R2 running through rooms:
if R2 zone-inhabits G:
decide on R2;
really decide on nothing.
To decide what number is maximum-goal-depth: (- MAXIMUM_GOAL_DEPTH -).
To decide what bare-array is prereq-bare-array: (- prereq_barearray -).
To decide what bare-array is goalstack-bare-array: (- goalstack_barearray -).
Include (-
Constant MAXIMUM_GOAL_DEPTH 18;
Array prereq_barearray table 11;
Array goalstack_barearray table (MAXIMUM_GOAL_DEPTH+2);
-).
Section - Goal Entry Points
[Game-callable utility phrase: perform an action goal. (This is called directly by the "perform ..." grammar.)]
To goal-perform (G - action-goal):
if G is not ever-done:
if G is recallable and G is known:
say "You've learned the ritual, but never performed it. Once you have gone through the steps, you'll have a better grasp of the technique.";
else:
say "You do not know how to do that.";
stop;
let origroom be the location;
ensure no ritual is left behind "Before you begin";
if attempt to achieve G:
do nothing;
if origroom is not the location:
say "(You are now [refer-preposition of location] [refer-name of location].)"
[Test whether performing a goal is possible. Should not affect state.]
[...I wound up not implementing this.
To decide whether goal-performance possible for (G - action-goal):
if G is not recallable:
decide no;
if G is not ever-done:
decide no;
if attempt to achieve G, hypothetically:
decide yes;
else:
decide no.
]
[Game-callable utility phrase: create a (currently offstage) object. (This is called directly by the "create ..." grammar.)]
To goal-create (T - thing):
if T is not recallable:
say "(BUG) [T] is not recallable.";
stop;
if the player carries T:
say "You're holding [the T].";
stop;
if T is not ever-seen:
say "You do not know what that is.";
stop;
let origroom be the location;
let loc be the holder of T;
let room-loc be loc;
while room-loc is not nothing and room-loc is not a room:
let room-loc be the holder of room-loc;
if room-loc is not nothing:
if room-loc is the location:
say "[The T] is right here.";
else:
say "[The T] is [refer-preposition of room-loc] [refer-name of room-loc], as you recall.";
stop;
ensure no ritual is left behind "Before you begin";
if attempt to achieve T:
do nothing;
if origroom is not the location:
say "(You are now [refer-preposition of location] [refer-name of location].)"
[Test whether creating a thing is possible. Should not affect state.]
[...I wound up not implementing this.
To decide whether goal-creation possible for (T - thing):
if T is not recallable:
decide no;
if the player carries T:
decide no; [?]
if T is not ever-seen:
decide no;
let loc be the holder of T;
let room-loc be loc;
while room-loc is not nothing and room-loc is not a room:
let room-loc be the holder of room-loc;
if room-loc is not nothing:
decide no; [?]
if attempt to achieve T, hypothetically:
decide yes;
else:
decide no.
]
[Game-callable utility phrase: go to where something is. (This is called directly by the "go to ..." grammar.)]
To goal-travel to (T - thing):
if T is not recallable:
say "(BUG) [T] is not recallable.";
stop;
if the player carries T:
say "You're holding [the T].";
stop;
if T is not ever-seen:
say "You do not know what that is.";
stop;
ensure no ritual is left behind "Before you leave";
let loc be nothing;
let room-loc be nothing;
[Follow transform chain if necessary.]
let transcount be zero;
while always:
let loc be the holder of T;
let room-loc be loc;
while room-loc is not nothing and room-loc is not a room:
let room-loc be the holder of room-loc;
if room-loc is nothing and T is handled and the fate of T is transformed-fate and transcount < 4:
let O be the fate-object of T;
say "[if transcount is zero]([The T][else], which[end if] became [the O]";
now T is O;
increment transcount;
next;
break;
if transcount is not zero:
say ".)";
if room-loc is nothing and the creation-action of T is a supply-action-goal:
[Sneakily swap in the supply object, which will have a simple location.]
let T be the creation-target of the creation-action of T;
now room-loc is the location of T;
set pronouns from T; [sorta wrong in a utility function, but appropriate for the "go to ..." grammar.]
if room-loc is nothing:
if T is not handled:
say "You have not made [the T], yet.";
else:
say "Impossible. ";
recall T at depth zero;
say ".";
stop;
if room-loc is the location:
say "[The T] is right here.";
stop;
say "[The T] is [refer-preposition of room-loc] [refer-name of room-loc], as you recall. You head that way.";
goal-travel to room-loc.
[Game-callable utility phrase: go to a room. (This is called directly by the "go to ..." grammar.)]
To goal-travel to (R - room):
if R is a reset-room:
[Special case; we presume that *some* reset-room is always accessible. R is going to be the Void-Room, rather than the nearest, but whatever.]
say "You make your way back to the Void.";
now the player is in R;
stop;
if the location is R:
say "You are already [refer-preposition of R] [refer-name of R].";
stop;
if R is not visited:
say "You do not know where that is.";
stop;
let origroom be the location;
let targetzone be the zone of R;
if targetzone is no-zone and the near-zone-room of R is not nothing and the near-zone-room of R is visited:
[Safe, but not very satisfactory to the player.]
say "You'll have to be more specific about getting to [refer-name of R].";
stop;
if targetzone is no-zone:
say "You're not sure how to get to [refer-name of R].";
stop;
ensure no ritual is left behind "Before you leave";
if targetzone is the current zone:
[There are no goal-obstacles; just go.]
now the player is in R;
stop;
if attempt to achieve R:
try looking; [### should restrict for brief mode!]
say going-look-break;
else:
if origroom is not the location:
say "(You are now [refer-preposition of location] [refer-name of location].)"
[Test whether going to a room is possible. Should not affect state.]
[...I wound up not implementing this.
To decide whether goal-travel possible to (R - room):
if the location is R:
decide yes;
if R is not visited:
decide no;
let origroom be the location;
let targetzone be the zone of R;
if targetzone is no-zone:
decide no;
if targetzone is the current zone:
[There are no goal-obstacles; just go.]
decide yes;
if origroom is not the location:
say "(BUG) Checking goal-travel possible caused the player to actually move from [origroom] to [location].";
if attempt to achieve R, hypothetically:
decide yes;
else:
decide no.
]
Section - Goal Internals
The goalstate is a thing.
The goalstate has a number called the depth. [require goal depth]
[The goalstate can be hypothetical.] [Not implemented.]
The goalstate has an object called the top-goal. The top-goal of goalstate is impossible-goal.
The goalstate can be latest-req-failed or latest-req-succeeded.
The goalstate can be error-stack-recited.
The goalstate has a room-goal called the zone-step-target.
The goalstate has a room called the pickup-room.
The goalstate has a room called the pickup-stretch-room.
The goalstate has an object called the pickup-holder.
The goalstate has a number called the room-count. [number of new rooms visited]
To decide whether goalstate is hypothetical: (- 0 -).
To decide whether goalstate is not hypothetical: (- 1 -).
[Top-level entry point to the goal mechanism.]
To decide whether attempt to achieve (G - object), hypothetically:
if goal-tracing:
say "(trace) setting up a goal attempt[if hypothetically] (hypothetical)[end if]...";
if the top-goal of goalstate is not impossible-goal:
say "(BUG) attempt-to-achieve was called recursively, and we don't support that.";
decide no;
completely suppress paragraph newlines;
[If this were recursive, we'd push existing goalstate here.]
now the top-goal of goalstate is G;
now the depth of goalstate is zero;
now the goalstate is not error-stack-recited;
now the goalstate is latest-req-failed;
now the zone-step-target of goalstate is no-zone;
now the room-count of goalstate is zero;
if hypothetically:
say "(BUG) 'Hypothetically' is not implemented.";
decide no;
[now the goalstate is hypothetical;]
[else:
now the goalstate is not hypothetical;]
clear the prereq-bare-array;
clear the goalstack-bare-array;
require G;
if the depth of goalstate is not zero:
say "(BUG) Goalstate depth wound up [depth of goalstate]!";
let top-req-succeeded be whether or not goalstate is latest-req-succeeded;
if not hypothetically:
[Do this while the goalstate still indicates goal-achieving.]
clean up timers remaining;
now the top-goal of goalstate is impossible-goal;
if goal-tracing:
say "(trace) end of goal attempt; success was [top-req-succeeded].";
[If this were recursive, we'd pop existing goalstate here.]
restore paragraph newlines;
if not hypothetically:
say "[line break][run paragraph on]";
decide on top-req-succeeded.
To decide whether goal-achieving:
if the top-goal of goalstate is not impossible-goal:
decide yes.
To decide whether goal-tracing: (- goal_tracing_flag -).
To decide whether goal-practiced: (- goal_practice_flag -).
[Shortcut for "require G; if goalstate is latest-req-failed, rule fails;"]
To require-or-fail (G - object): (-
( (+ goal-requiring +)-->1 ) ( {G} );
if (GetEitherOrProperty( (+ goalstate +), (+ latest-req-failed +) )) {
RulebookFails(); rtrue;
}
-).
[Same as above, but it also sets a boolean local whether you already had the thing. Note that we invoke the goal machinery even if the thing seems to be already carried.]
To require-or-fail (G - thing) noting (hadflag - nonexisting truth state variable): (-
{hadflag} = ( (+ takeable +) ( {G} ) && parent( {G} ) == (+ player +) );
( (+ goal-requiring +)-->1 ) ( {G} );
if (GetEitherOrProperty( (+ goalstate +), (+ latest-req-failed +) )) {
RulebookFails(); rtrue;
}
-).
[An ad-hoc shortcut for invoking the "goal environment available" utility.]
To attain-or-fail environment (E - ritual-env) noting (tool - nonexisting thing variable): (-
! Set up the input "argument" of the goal.
WriteGProperty(OBJECT_TY, (+ create-ritual-env-goal +), (+ goal-env +), {E});
( (+ goal-requiring +)-->1 ) ( (+ create-ritual-env-goal +) );
if (GetEitherOrProperty( (+ goalstate +), (+ latest-req-failed +) )) {
RulebookFails(); rtrue;
}
{tool} = GProperty(OBJECT_TY, (+ create-ritual-env-goal +), (+ goal-env-tool +));
! Clear the output "argument" of the goal.
WriteGProperty(OBJECT_TY, (+ create-ritual-env-goal +), (+ goal-env-tool +), (+ no-thing +));
-).
To auto-drop (T - thing):
if T is nothing or T is no-thing:
stop;
if the player does not carry T:
say "(BUG) Cannot auto-drop [T].";
stop;
now T is handled;
if T is an impet:
now T is closed;
now T is in the location.
To auto-drop (T - thing) unless (skip - truth state):
unless bool skip:
auto-drop T.
To auto-drop (T - thing) if (doit - truth state):
if bool doit:
auto-drop T.
To recite the goal stack:
now goalstate is error-stack-recited;
let N be the count of goalstack-bare-array;
let flag be true;
let prev-G be nothing;
while N > 0:
decrement N;
let G be object N of goalstack-bare-array;
if G is an undescribed action-goal:
continue the loop;
if G is a thing and the creation-action of G is prev-G:
continue the loop;
if flag is true:
say "(While trying to ";
else:
say ", to ";
now flag is false;
if G is an action-goal:
say short-description of G;
else if G is a room-goal:
let R be the canonical room of G;
say "reach [refer-name of R]";
else if G is a room:
say "reach [refer-name of G]";
else if G is a thing:
say "acquire [the G]";
else:
say "[G]";
now prev-G is G;
if flag is false:
say ".)"
[Invoke one goal in the goal tree; will recursively require more goals. G must be a room-goal, an actual room, an action-goal, or a takeable.]
To require (G - object) (this is goal-requiring):
if the top-goal of goalstate is impossible-goal:
say "(BUG) require (-or-fail) was called outside an attempt-to-achieve.";
stop;
if goal-tracing:
say "(trace) (depth [depth of goalstate]) require [objname G].";
if depth of goalstate >= maximum-goal-depth:
now the goalstate is latest-req-failed;
if goalstate is not hypothetical:
say "This has become too confusing. You stop.";
if goalstate is not error-stack-recited:
recite the goal stack;
stop;
if G is not reentrant and the object G is listed in goalstack-bare-array:
now the goalstate is latest-req-failed;
add G to goalstack-bare-array;
if goalstate is not hypothetical:
say "This is impossible, so you stop.";
if goalstate is not error-stack-recited:
recite the goal stack;
stop;
increment depth of goalstate;
add G to goalstack-bare-array;
if the depth of goalstate is not the count of goalstack-bare-array:
say "(BUG) goalstack-bare-array size does not match depth.";
now the goalstate is latest-req-failed;
if G is an action-goal:
if generic action prereqs for G succeeded:
now the goalstate is latest-req-succeeded;
else:
now the goalstate is latest-req-failed;
else if G is a room-goal:
let R be the canonical room of G;
if generic zone prereqs for R in G succeeded:
now the goalstate is latest-req-succeeded;
else:
now the goalstate is latest-req-failed;
else if G is a room:
if generic zone prereqs for G in zone of G succeeded:
now the goalstate is latest-req-succeeded;
else:
now the goalstate is latest-req-failed;
else if G is a thing:
if generic thing prereqs for G succeeded:
now the goalstate is latest-req-succeeded;
else:
now the goalstate is latest-req-failed;
else:
say "(BUG) require [objname G] invoked, but that is not a goal or thing.";
decrement depth of goalstate;
remove last from goalstack-bare-array;
if the goalstate is latest-req-failed and goalstate is not error-stack-recited and goalstate is not hypothetical:
recite the goal stack;
[if goal-tracing:
say "(trace) (depth [depth of goalstate]) exiting [objname G]; latest req [if goalstate is latest-req-succeeded]succeeded[else]failed[end if].";]
To decide whether generic thing prereqs for (G - thing) succeeded:
if G is not takeable:
say "(BUG) Tried to require [objname G], which is not takeable.";
decide no;
if G is not ever-seen:
if goalstate is not hypothetical:
say "You do not know how to proceed.";
if not release mode:
say "(DEBUG) ...with thing [objname G].";
decide no;
if goalstate is hypothetical and G is barelist-in prereq-bare-array:
decide yes;
let loc be the holder of G;
if loc is the player:
decide yes;
let room-loc be loc;
while room-loc is not nothing and room-loc is not a room:
let room-loc be the holder of room-loc;
let creategoal be the creation-action of G;
if room-loc is nothing and creategoal is not impossible-goal and creategoal is ever-done:
require creategoal;
if goalstate is latest-req-failed:
decide no;
if goalstate is hypothetical:
add G to prereq-bare-array;
else:
if the player does not carry G:
say "(BUG) Goal create action for [objname G] succeeded, but G is not carried.";
decide no;
decide yes;
else if room-loc is nothing:
if goalstate is not hypothetical:
recall G at depth zero;
if G is handled:
say ". You don't know where to get ";
if G is plural-named or G is mass-named:
say "more";
else:
say "another one";
say ".";
decide no;
else:
if room-loc is not visited:
if goalstate is not hypothetical:
say "You do not know where [the G] is.";
decide no;
let targetzone be the zone of room-loc;
let stretchroom be room-loc;
if targetzone is no-zone and the near-zone-room of room-loc is not nothing and the near-zone-room of room-loc is visited:
now room-loc is the near-zone-room of room-loc;
now targetzone is the zone of room-loc;
if targetzone is no-zone:
say "(BUG) zone of a near-zone-room is no-zone.";
decide no;
if targetzone is no-zone:
if goalstate is not hypothetical:
say "You're not sure how to get to [refer-name of room-loc].";
decide no;
if room-loc is the location:
do nothing;
else if targetzone is the current zone:
if goalstate is not hypothetical:
say "You head to [refer-name of room-loc].";
move the player to room-loc, without printing a room description;
else:
require room-loc;
if goalstate is latest-req-failed:
decide no;
if goalstate is not hypothetical:
[travel message was handled by the require call]
move the player to room-loc, without printing a room description;
[only needs to persist until the pickup rule begins]
now the pickup-room of goalstate is room-loc;
now the pickup-stretch-room of goalstate is stretchroom;
now the pickup-holder of goalstate is loc;
follow the goal pickup rules for G;
if rule failed:
decide no;
if goalstate is hypothetical:
add G to prereq-bare-array;
else:
if the player does not carry G:
say "(BUG) Goal pickup rules for [objname G] succeeded, but G is not carried.";
decide no;
decide yes.
[Deals with picking up (existent) objects for thing goals. Presume that the player is in pickup-room (although this will not be true for hypothetical attempts).]
The goal pickup rulebook is a thing based rulebook.
Goal pickup rule for a thing (called G) when the pickup-holder of goalstate is the kiln or the pickup-holder of goalstate is in the kiln (this is the kiln pickup rule):
if not currently fireproof and kiln-reach-goal is ever-done:
require-or-fail kiln-reach-goal;
else if not currently fireproof:
if goalstate is not hypothetical:
say "[The G] is in the kiln, and you're not fireproof.";
rule fails;
require-or-fail the location of the kiln;
if goalstate is not hypothetical:
say "You reach into the kiln and take [the G].";
now the player carries G;
rule succeeds.
Goal pickup rule for a thing (called G) when the pickup-holder of goalstate is the retort (this is the retort pickup rule):
if rstate is active:
if goalstate is not hypothetical:
say "[The G] is within an active ritual.";
rule fails;
if goalstate is not hypothetical:
say "[The G] is currently inside the retort.";
rule fails.
Goal pickup rule for a thing (called G) when the pickup-holder of goalstate is a ritual-bound (this is the ritual-bound pickup rule):
if rstate is active:
if goalstate is not hypothetical:
say "[The G] is within an active ritual.";
rule fails;
if goalstate is not hypothetical:
say "You take [the G] from [the pickup-holder of goalstate].";
now the player carries G;
rule succeeds.
Goal pickup rule for a thing (called G) when the pickup-room of goalstate is not the pickup-stretch-room of goalstate (this is the give-up-on-stretch pickup rule):
if goalstate is not hypothetical:
say "You'll have to be more specific about reaching [refer-name of pickup-stretch-room of goalstate].";
rule fails.
Goal pickup rule for a thing (called G) when the pickup-room of goalstate is the pickup-holder of goalstate (this is the standard lying-on-the-floor pickup rule):
if goalstate is not hypothetical:
say "You take [the G].";
now the player carries G;
rule succeeds.
Last goal pickup rule for a thing (called G) when the pickup-holder of goalstate is an open container (this is the general container pickup rule):
if goalstate is not hypothetical:
say "You take [the G] from [the pickup-holder of goalstate].";
now the player carries G;
rule succeeds.
Last goal pickup rule for a thing (called G) when the pickup-holder of goalstate is a supporter (this is the general supporter pickup rule):
if goalstate is not hypothetical:
say "You take [the G] from [the pickup-holder of goalstate].";
now the player carries G;
rule succeeds.
The last goal pickup rule for a thing (called G) (this is the last-ditch give-up pickup rule):
if goalstate is not hypothetical:
say "You cannot reach [the G].";
rule fails.
[This covers all action goals.]
The goal prereqs rulebook is a goal based rulebook.
To decide whether generic action prereqs for (G - action-goal) succeeded:
if G is not ever-done:
if goalstate is not hypothetical:
say "You're not sure how to proceed.";
if not release mode:
say "(DEBUG) ...with goal [objname G].";
decide no;
follow the goal prereqs for G;
if rule succeeded:
decide yes;
else:
decide no.
Goal prereqs rule for the impossible-goal:
[Say nothing.]
rule fails.
The last goal prereqs rule for a goal (called G):
say "(BUG) unhandled goal prereqs for [objname G].";
rule fails.
To decide whether generic zone prereqs for (targetroom - room) in (targetzone - room-goal) succeeded:
if targetzone is no-zone:
say "(BUG) Tried to require the no-zone.";
decide no;
if targetroom is-room off-stagey:
say "(BUG) Tried to require the no-place.";
decide no;
let origzone be the current zone;
if origzone is no-zone:
if goalstate is not hypothetical:
say "Get out of here first; then you can worry about finding your way around.";
decide no;
if origzone is targetzone:
if goalstate is not hypothetical:
move the player to targetroom, without printing a room description;
decide yes;
let curzone be origzone;
let steps be zero;
while always:
if steps > 12:
say "(BUG) Go-to tracker apparently got stuck! (Going from [origzone] to [targetzone].) That's bad.";
decide no;
now the zone-step-target of goalstate is targetzone; [only needs to persist until the zone step rule begins]
if goal-tracing:
say "(trace) step from [curzone] to [targetzone].";
let newzone be the room-goal produced by the zone step rulebook for curzone;
if newzone is nothing:
decide no;
if newzone is no-zone:
say "You're not sure which way to go.";
decide no;
if newzone is targetzone:
if goalstate is not hypothetical:
say "You make your way to [refer-name of targetroom].";
move the player to targetroom, without printing a room description;
decide yes;
now curzone is newzone;
if goalstate is not hypothetical:
move the player to canonical room of curzone, without printing a room description;
increment steps.
[Zone step rule for CURZONE (from CURZONE to zone-step-target of goalstate)]
The zone step rulebook is a room-goal based rulebook producing a room-goal.
The last zone step rule for a room-goal (called G):
say "(BUG) [objname G] step rule: not implemented.";
rule fails.
[Called at the end of any (top-level) goal attempt, successful or not. The extra tick simulates the extra passage of time for a compound action. It also ensures that any potion drunk in the goal attempt wears off right away.]
To clean up timers remaining:
[A goal that fails instantly shouldn't trigger these timers. Ditto a goal which is so simple that you can do it in place.]
if the room-count of goalstate is not zero:
[To be nice (and to avoid taking actions in a "compressed" context), we skip this step if the goal ended underwater. Successful goals don't end underwater, but failed goals might.]
if the atmosphere of the location is not water-atm:
follow the breath daemon rule;
[Similarly.]
if the atmosphere of the location is not fire-atm:
follow the fire-resistance daemon rule.
Section - The Fates of Things
[Our model: "handled" is the master switch. An unhandled object is in its original place (if onstage) or it never existed (if offstage). The fate is only meaningful for offstage, handled things. For those, we can recall what happened, possibly with an argument -- although the argument may always be missing. (Shortcut actions probably won't set it.)]
An offstage-fate is a kind of value.
A thing has an offstage-fate called the fate.
A thing has an object called the fate-object.
A thing has some text called the fate-text.
The verb to retire to (it retired to, they retired to, it was retired to) implies the fate property.
The verb to retire with (it retired with, they retired with, it was retired with) implies the fate-object property.
The offstage-fates are no-fate, text-fate, wrecked-fate, transformed-fate, chasm-fate, maze-fate, drunk-fate, dissolved-fate, incinerated-fate, water-fate, aeroclave-fate, vacuum-fate, burned-fate, burnout-fate, applied-fate, ritual-fate, chymic-fate.
The fate of a thing is usually no-fate.
The fate-object of a thing is usually nothing.
To retire (T - thing) vaguely:
now T is off-stage;
now T is handled;
now T is ever-seen;
now the fate of T is no-fate.
To retire (T - thing) with explanation (msg - text):
now T is off-stage;
[don't handle or mark ever-seen; leave that to the caller.]
now the fate of T is text-fate;
now the fate-text of T is msg.
To retire (T - thing) by ritual-or-alchemy:
if rstate is active:
retire T by ritual;
else:
retire T by alchemy.
To retire (T - thing) by ritual:
now T is off-stage;
now T is handled;
now T is ever-seen;
now the fate of T is ritual-fate;
now the fate-object of T is the location.
To retire (T - thing) by ritual in (R - room):
now T is off-stage;
now T is handled;
now T is ever-seen;
now the fate of T is ritual-fate;
now the fate-object of T is R.
To retire (T - thing) by alchemy:
now T is off-stage;
now T is handled;
now T is ever-seen;
now the fate of T is chymic-fate;
now the fate-object of T is the location.
To retire (T - thing) by drinking:
now T is off-stage;
now T is handled;
now T is ever-seen;
now the fate of T is drunk-fate;
now the fate-object of T is the location.
To retire (T - thing) by drinking in (R - room):
now T is off-stage;
now T is handled;
now T is ever-seen;
now the fate of T is drunk-fate;
now the fate-object of T is R.
To retire (T - thing) by burning out:
now T is off-stage;
now T is handled;
now T is ever-seen;
now the fate of T is burnout-fate.
To retire (T - thing) by burning in (cause - thing):
now T is off-stage;
now T is handled;
now T is ever-seen;
now the fate of T is burned-fate;
now the fate-object of T is cause.
To retire (T - thing) by applying to (target - thing):
now T is off-stage;
now T is handled;
now T is ever-seen;
now the fate of T is applied-fate;
now the fate-object of T is target.
To retire (T - thing) by dissolution in (cause - thing):
now T is off-stage;
now T is handled;
now T is ever-seen;
now the fate of T is dissolved-fate;
now the fate-object of T is cause.
To retire (T - thing) by manual destruction:
now T is off-stage;
now T is handled;
now T is ever-seen;
now the fate of T is wrecked-fate;
now the fate-object of T is nothing.
To retire (T - thing) by manual destruction in (cause - thing):
now T is off-stage;
now T is handled;
now T is ever-seen;
now the fate of T is wrecked-fate;
now the fate-object of T is cause.
To retire (T - thing) by transformation into (result - thing):
now T is off-stage;
now T is handled;
now T is ever-seen;
now the fate of T is transformed-fate;
now the fate-object of T is result.
To retire (T - thing) by chasm-plummeting:
now T is off-stage;
now T is handled;
now T is ever-seen;
now the fate of T is chasm-fate.
To retire (T - thing) by maze-discarding:
now T is off-stage;
now T is handled;
now T is ever-seen;
now the fate of T is maze-fate.
Section - Recalling Things
[For stitchability, this routine does *not* print a closing period.]
[This whole routine uses "[The T]" rather than "[remote-name of T]", which is wrong, but capitalization is screwing me here. If I yank "the" out of remote-names, then we get mentions of "the yourself" and probably other proper nouns.]
To recall (T - thing) at depth (depth - number):
if T is not recallable:
say "(BUG) [T] is not recallable";
stop;
if T is not ever-seen:
say "You do not know what that is";
stop;
let loc be the holder of T;
let room-loc be loc;
while room-loc is not nothing and room-loc is not a room:
let room-loc be the holder of room-loc;
if room-loc is nothing and the creation-action of T is a supply-action-goal:
if depth is not zero:
say ". ";
let supply be the creation-target of the creation-action of T;
let suploc be the location of supply;
say "[The supply] is [refer-preposition of suploc] [refer-name of suploc]";
stop;
if room-loc is nothing:
if T is not handled:
if depth is not zero:
say ". ";
say "You have not made [the T], yet";
else if depth > 3:
say ", and then you lost track";
else:
if the fate of T is:
-- no-fate:
say "[if depth is zero][The T][else], which";
say " [is-are T] gone";
-- text-fate:
say fate-text of T;
-- wrecked-fate:
if depth is zero:
say "You destroyed [the T]";
else:
say ", which you destroyed";
let O be the fate-object of T;
if O is not nothing:
say " in [the O]";
-- burned-fate:
if depth is zero:
say "You burned [the T]";
else:
say ", which you burned";
let O be the fate-object of T;
if O is not nothing:
if O is a wood-splint:
say " using [remote-name of O]";
else if O is phlo-gold or O is phlo-electrum:
say " using elemental fire";
else:
say " in [remote-name of O]";
-- applied-fate:
if depth is zero:
say "You applied [the T] to";
else:
say ", which you applied to";
let O be the fate-object of T;
if O is nothing:
say " something";
else:
say " [remote-name of O]";
-- transformed-fate:
say "[if depth is zero][The T][else], which";
say " became";
let O be the fate-object of T;
if O is nothing:
say " something else";
else:
say " [remote-name of O]";
recall O at depth ( depth + 1 );
-- chymic-fate:
if depth is zero:
say "[The T] is gone; you added it to a chymic mixture";
else:
say ", which you added to a chymic mixture";
say recall location fate-object of T;
-- ritual-fate:
if depth is zero:
say "[The T] is gone; you used it in a ritual";
else:
say ", which you used in a ritual";
say recall location fate-object of T;
-- drunk-fate:
if depth is zero:
say "You drank [the T]";
else:
say ", which was drunk";
say recall location fate-object of T;
-- vacuum-fate:
say "[if depth is zero][The T][else], which";
say " [was-were T] destroyed by vacuum exposure";
say recall location fate-object of T;
-- water-fate:
say "[if depth is zero][The T][else], which";
say " [was-were T] ruined by water";
if fate-object of T is not nothing:
say " in [refer-name of fate-object of T]";
-- aeroclave-fate:
say "[if depth is zero][The T][else], which";
say " [was-were T] destroyed by elemental air";
-- dissolved-fate:
if depth is zero:
say "You dissolved [the T]";
else:
say ", which you dissolved";
let O be the fate-object of T;
if O is not nothing:
say " with [the O]";
-- incinerated-fate:
say "[if depth is zero][The T][else], which";
say " [was-were T] incinerated";
say recall location fate-object of T;
-- burnout-fate:
say "[if depth is zero][The T][else], which";
say " [is-are T] gone; you let it burn away";
-- chasm-fate:
if depth is zero:
say "You lost [the T] in a chasm";
else:
say ", which was lost in a chasm";
-- maze-fate:
if depth is zero:
say "You lost [the T] in the maze";
else:
say ", which was lost in the maze";
-- otherwise:
say "(BUG) [The T] retired to [fate of T]";
stop;
[...begin the on-stage case]
if loc is the player:
if depth is zero:
say "You're holding [the T]";
else:
say ", which you're holding";
stop;
let adverb be a text;
if T is sessile:
now adverb is "";
else if T is not handled:
now adverb is " still";
else:
now adverb is " now";
if room-loc is not visited-this-cycle:
say "[if depth is zero]You[else]. You";
say " have not been there yet, but you presume [the T]";
say " [is-are T]";
if T is not handled:
now adverb is " waiting";
else:
say "[if depth is zero][The T][else], which";
say " [is-are T]";
if loc is not room-loc:
if T is part of loc:
say "[adverb] within";
else if loc is a container:
say "[adverb] in";
else:
say "[adverb] on";
say " [the loc]";
if the room-loc is the location:
say " (right here)";
else:
say " ([refer-preposition of room-loc] [refer-name of room-loc])";
else:
if the room-loc is the location:
say " right here";
say " ([refer-preposition of room-loc] [refer-name of room-loc])";
else:
say "[adverb] [refer-preposition of room-loc] [refer-name of room-loc]";
stop.
To say recall (T - thing) briefly:
[like the above, but as "you're holding it" or "it's in the Kitchen". No history, no punctuation.]
let loc be the holder of T;
let room-loc be loc;
while room-loc is not nothing and room-loc is not a room:
let room-loc be the holder of room-loc;
if room-loc is nothing:
say "it's gone";
else if loc is the player:
say "you're holding it";
else if loc is not room-loc:
say "it's";
if T is part of loc:
say " within";
else if loc is a container:
say " in";
else:
say " on";
say " [the loc]";
if the room-loc is the location:
say " (right here)";
else:
say " ([refer-preposition of room-loc] [refer-name of room-loc])";
else:
say "it's";
if the room-loc is the location:
say " right here";
say " ([refer-preposition of room-loc] [refer-name of room-loc])";
else:
say " [refer-preposition of room-loc] [refer-name of room-loc]";
stop.
To say recall location (R - room):
if R is nothing:
stop;
if R is the location:
say ", here";
say " [refer-preposition of R] [refer-name of R]"
To say recall location (T - thing):
if T is nothing:
stop;
say " in [the T]"
Chapter - Pure Information
Section - Magic Words
A formula is a kind of object.
A formula can be privately-named or publically-named. A formula is usually publically-named. [They are typable.]
Understand "formula" as a formula when the item described is not xyzzy.
A formula has a text called the description.
A formula can be known or unknown. A formula is usually unknown.
A formula can be sealish or nonsealish. A formula is usually nonsealish.
A formula can be vocal or nonvocal. A formula is usually vocal.
To mark (F - formula) as known: (- MarkFormulaKnown({F}); -).
Include (-
[ MarkFormulaKnown form;
if (form == nothing) {
print "(BUG) MarkFormulaKnown(", (name) form, ")!^";
return;
}
if (form == (+ xyzzy +) ) {
! This should never wind up listed in known-formulas.
return;
}
if (~~(form in (+ known-formulas +) )) {
move form to (+ known-formulas +);
}
SetEitherOrProperty(form, (+ known +) );
];
-).
The known-formulas is a container.
When play begins (this is the known-formulas container setup rule):
repeat with F running through known formulas:
mark F as known.
Check invoking a vocal formula when the location is airless:
if the atmosphere of the location is water-atm:
instead say "You can't speak; you're holding your breath.";
instead say "You can't speak; there's no air."
The alien-glyph non-ritual invocation rule is listed before the generic non-ritual formula invocation rule in the carry out invoking rulebook.
Carry out invoking an alien-glyph (this is the alien-glyph non-ritual invocation rule):
if the noun is consumed:
instead say "You try to visualize [the noun], but the shape doesn't seem interesting any more.";
instead say "You have no idea how it's pronounced, but you visualize [the noun] as clearly as possible. Nothing seems to result, however."
The alien-pattern non-ritual invocation rule is listed before the generic non-ritual formula invocation rule in the carry out invoking rulebook.
Carry out invoking an alien-pattern (this is the alien-pattern non-ritual invocation rule):
instead say "You begin running through the geometric sequence in your head. When you reach the end, you feel slightly dizzy, but there is no other result."
Carry out invoking the resonant-tone:
instead say "You hum the resonant tone, but there is no effect."
Carry out invoking an nonsealish formula when the rstate is active:
instead try rit-speaking the noun.
Carry out invoking an nonsealish formula (this is the generic non-ritual formula invocation rule):
tutor tut-formula-outside-ritual;
instead say "You [one of]say[or]recite[or]invoke[or]speak[at random] [the noun][one of]. Nothing happens[or], but nothing results[or]. There is no effect[or], but there is no effect[at random]."
Carry out invoking a sealish formula:
if a ritual-bound (called B) is in the location:
instead try rit-sealing B with the noun;
instead say "You [one of]say[or]recite[or]invoke[or]speak[at random] [the noun]. But there is no ritual bound here to concentrate on, so [one of]nothing happens[or]there is no effect[purely at random]."
Carry out invoking an sealish formula when the rstate is active:
say "The ritual is already in progress. [if the initial-sealing of rstate is the noun]Repeating the sealing word[else]Invoking another sealing word[end if] would tangle the bound";
unless chapter-1-done:
say ". If you want to start over, you'll have to halt the ritual first, by reciting your unsealing mantra";
instead say "."
The no-word is a formula.
Understand "word", "word of", "fake", "fake-word" as the no-word.
The unseal-word is a known formula. The printed name is "unsealing mantra".
The description is "The unsealing mantra isn't an alchemical formula. It's just a way to divert your mind from a ritual in progress, breaking open the bound and dissipating any energies."
Understand "mantra", "unsealing", "unseal", "unbinding", "unbind" as the unseal-word.
Carry out invoking the unseal-word:
instead say "You chant the unsealing mantra. [one of]But[or]However,[purely at random] [one of]you are not concentrating on any ritual[or]no ritual is in progress[cycling], so there's nothing to [one of]unseal[or]break[purely at random]."
Carry out invoking the unseal-word when the rstate is active:
tutor tut-step-unseal;
say "You let the unsealing mantra run through your mind, clearing away the ritual energy. The bound goes dark.";
shut down the ritual state;
stop.
The simple-seal-word is a known sealish formula. The printed name is "simple sealing word".
The description is "The simple sealing word creates a boundary circle around a ritual space. Most alchemical procedures begin with a sealing word."
Understand "simple", "sealing", "word" as the simple-seal-word.
The ka-seal-word is a sealish formula. The printed name is "Ka Sealing". The indefinite article is "the".
The description is "The Ka Sealing word creates a boundary circle. It is derived from the Classical Egyptian analytical model of the human mind, or spirit."
Understand "ka", "sealing", "word" as the ka-seal-word.
The hermetic-seal-word is a sealish formula. The printed name is "Hermetic Sealing". The indefinite article is "the".
The description is "The Hermetic Sealing word creates a boundary circle. It is always used for chymical transformations in the retort, although it has other uses as well."
Understand "hermetic", "sealing", "word" as the hermetic-seal-word.
The shamash-seal-word is a sealish formula. The printed name is "Sealing of Shamash". The indefinite article is "the".
The description is "The Sealing of Shamash creates a boundary circle. It comes from a Babylonian ritual tradition, where it is associated with order, the calendar, and clockwork[first time]. You didn't know the Babylonians [em]had[/em] clockwork, but that's what the textbook said[only]."
Understand "shamash", "sealing", "sealing of" as the shamash-seal-word.
The mithraic-seal-word is a sealish formula. The printed name is "Mithraic Sealing". The indefinite article is "the".
The description is "The Mithraic Sealing word creates a boundary circle. The Mithraic tradition is a mystery cult, associated with labyrinths and secrets."
Understand "mithraic", "sealing", "word" as the mithraic-seal-word.
The phlegmatic-seal-word is a sealish formula. The printed name is "phlegmatic sealing word".
The description is "The phlegmatic sealing word creates a boundary circle. It has a stable, passive pattern -- Yin in the Oriental traditions, cool and moist in the Greek."
Understand "phlegmatic", "sealing", "word" as the phlegmatic-seal-word.
The grendel-seal-word is a proper-named sealish formula. The printed name is "Grendel's Sealing".
The description is "Grendel's Sealing creates a boundary circle. It is used in dragon-ordering rituals. (The marcher-construct sort of dragon, that is.) It derives from an Old English narrative tradition of dragon-hunting. (The scaly mythical sort.)"
Understand "grendel", "grendels", "grendel's", "sealing" as the grendel-seal-word.
The marcher-seal-word is a sealish formula. The printed name is "Marcher's Sealing". The indefinite article is "the".
The description is "The Marcher's Sealing creates a boundary circle. You recall it from the great rituals that launch the [Retort] and bring it home."
Understand "marcher", "marcher's", "sealing", "invocation" as the marcher-seal-word.
The nature-word is a known formula. The printed name is "word of essential nature".
The description is "[tutor tut-saw-nature]The word of essential nature is used in rituals to invoke the principle of sympathy."
Understand "word", "word of", "essential", "nature" as the nature-word.
The anaphylaxis-word is a formula. The printed name is "word of anaphylaxis".
The description is "The word of anaphylaxis inflames the sensitivity of contrary elements."
Understand "word", "word of", "anaphylaxis" as the anaphylaxis-word.
The emulgence-word is a formula. The printed name is "word of emulgence".
The description is "The word of emulgence allows immiscible elements to blend into a homogenous composition."
Understand "word", "word of", "emulgence" as the emulgence-word.
The entension-word is a formula. The printed name is "word of entension".
The description is "The word of entension delays a reaction, which can later be resolved by a word of culmination."
Understand "word", "word of", "entension" as the entension-word.
The culmination-word is a formula. The printed name is "word of culmination".
The description is "The word of culmination resolves a reaction which has been delayed by a word of entension."
Understand "word", "word of", "culmination" as the culmination-word.
The binding-word is a known formula. The printed name is "elementary word of binding".
The description is "The elementary word of binding is frequently used to make simple chymical compounds."
Understand "word", "word of", "elementary word of", "elementary", "binding" as the binding-word.
The Crystalline Tempering is a formula. The indefinite article is "the".
The description is "The Crystalline Tempering is a rhythmic chain of sounds, which tends to pull mineral substances into more regular order."
Understand "crystal tempering" as the Crystalline Tempering.
The Anodyne Evocation is a formula. The indefinite article is "the".
The description is "The Anodyne Evocation aids the health and growth of the body."
The Celestial Sphere is a formula. The printed name is "Binding of the Celestial Sphere". The indefinite article is "the".
The description is "The Binding of the Celestial Sphere is appropriate for astrological constructs and compounds of aither."
Understand "binding", "binding of" as the Celestial Sphere.
The tortoise-name is a formula. The printed name is "Name of the Tortoise". The indefinite article is "the".
The description is "The Name of the Tortoise is an elemental invocation of water, in the fivefold Oriental symbology."
Understand "name", "name of", "tortoise", "turtle" as the tortoise-name.
The binding-antipathy is a formula. The printed name is "Binding of Antipathy". The indefinite article is "the".
The description is "The Binding of Antipathy can hold contradictory elements in accord, or amplify an element's opposition to external influences."
Understand "binding", "binding of", "antipathy" as the binding-antipathy.
The chi-binding is a formula. The printed name is "Chi Binding". The indefinite article is "the".
The description is "The Chi Binding is an elemental binding used in certain Chinese ritual traditions, particularly the syntheses of the Song Dynasty."
Understand "chi", "ki", "qi", "binding" as the chi-binding.
The counterbalance is a formula. The printed name is "syllable of counterbalance".
The description is "The syllable of counterbalance is a precise phoneme cluster which permits opposing forces to be brought into stasis."
Understand "syllable", "syllable of" as the counterbalance.
The resonant-tone is a formula. The printed name is "resonant tone".
The description is "The tone is a particular pitch that resonates with the structure of matter. It allows substances to be tuned for various vibrational effects."
Understand "resonant", "resonance", "tone" as the resonant-tone.
The categorical imperative is a formula. The indefinite article is "the".
The description is "The categorical imperative is a phonological argument for generalizing a transformation."
The Lesser Phlogistical Saturation is a formula. The indefinite article is "the".
The description is "The Lesser Phlogistical Saturation is a knot of breathy syllables. It has to do with reversing processes of tarnish and rust."
The Greater Phlogistical Saturation is a formula. The indefinite article is "the".
The description is "The Greater Phlogistical Saturation is a tonal chain of bitten-off sounds and exhalations. It has to do with reversing processes of tarnish and rust."
The Phlogistical Catalysis is a formula. The indefinite article is "the".
The description is "The Phlogistical Catalysis is a tedious sequence of murmuring. It's used to stabilize some of the more complex chymical reagents."
[Understand "catalytic" as the Phlogistical Catalysis.] [No, don't collide with the catalytic-env-note.]
The Major Animus is a formula.
The description is "The Major Animus is a complex, polyrhythmic glottal intonation. It can impart significant changes in kinetic energy, under controlled circumstances."
The Minor Animus is a formula.
The description is "The Minor Animus is a rhythmic glottal intonation. It can impart small changes in kinetic energy, slightly altering the movement of an object."
The Mediate Anima is a formula.
The description is "The Mediate Anima is a complex ululation of vowels. It can modulate the forces between moving objects."
The Relative Anima is a formula.
The description is "The Relative Anima is a complex ululation of vowels. It can serve as an eye of stability among moving objects."
The idempotent group is a formula.
The description is "The idempotent group is a mathematical structure which maps many things to one thing."
Understand "idempot" as the idempotent group.
The isomorphic group is a formula.
The description is "The isomorphic group is a mathematical structure which maps things to equivalent things."
Understand "isomorph" as the isomorphic group.
The symmetric sequence is a formula.
The description is "The symmetric sequence is a mathematical structure which is the same back-to-front."
The antisymmetric sequence is a formula.
The description is "The antisymmetric sequence is a mathematical structure which is upside-down back-to-front."
Understand "anti", "anti-symmetric" as the antisymmetric sequence.
The dracon-invocation is a formula. The printed name is "Dracon Invocation". The indefinite article is "the".
The description is "The Dracon Invocation has something to do with dragons, clearly."
Understand "dragon", "dracon", "invocation" as the dracon-invocation.
An alien-glyph is a kind of formula.
An alien-glyph is usually nonvocal.
The indefinite article of an alien-glyph is usually "the".
The description of an alien-glyph is usually "The glyph is [short-description]. The glyph [if unconsumed]burns in your memory like something startling you have always known[else]feels familiar, no longer startling[end if]."
An alien-glyph can be consumed or unconsumed.
An alien-glyph has some text called the short-description.
Understand "alien", "glyph" as an alien-glyph.
After printing the name of an alien-glyph when the current action is recallish:
if the item described is consumed:
say " (spent)".
The glyph-1 is an alien-glyph. The printed name is "[if glyph-2 is known]first [end if]alien glyph".
The short-description is "a multidimensional structure -- a surface which is curved back on itself, but with no edges".
Understand "first" as glyph-1 when glyph-2 is known.
The glyph-2 is an alien-glyph. The printed name is "second alien glyph".
The short-description is "a multidimensional knot of curves and gaps".
Understand "second" as glyph-2.
The glyph-3 is an alien-glyph. The printed name is "third alien glyph".
The short-description is "a multidimensional helix which bends back on itself without end".
Understand "third" as glyph-3.
The glyph-4 is an alien-glyph. The printed name is "fourth alien glyph".
The short-description is "a multidimensional flower of petals which curve into each other, surrounding an edgeless space".
Understand "fourth" as glyph-4.
An alien-pattern is a kind of formula.
An alien-pattern is usually nonvocal.
The indefinite article of an alien-pattern is usually "the".
Understand "alien", "pattern", "geometric", "sequence" as an alien-pattern.
The radix-pattern is an alien-pattern. The printed name is "[em]radix access[/em] pattern".
The description is "A sequence of outward geometric relations, forming a pattern which you can barely hold in your mind's eye."
Understand "radix", "outward", "access" as the radix-pattern.
The caudex-pattern is an alien-pattern. The printed name is "[em]caudex access[/em] pattern".
The description is "A sequence of inward geometric relations, forming a pattern which you can barely hold in your mind's eye."
Understand "caudex", "inward", "access" as the caudex-pattern.
The calyx-pattern is an alien-pattern. The printed name is "[em]calyx access[/em] pattern".
The description is "A sequence of semantic relations, forming a pattern which you can barely hold in your mind's eye. The pattern has the scent of dragon about it."
Understand "calyx", "access" as the calyx-pattern.
The xyzzy is a known formula. The printed name is "silly magic word".
The description is "You read about this magic word in a fantasy novel once."
Understand "plugh", "frotz", "gnusto" as the xyzzy.
Check invoking xyzzy:
instead say "You don't know how to pronounce that."
Section - Tidbits of Knowledge
A tidbit is a kind of object.
[We presume they're all recallable.]
A tidbit can be privately-named or publically-named. A tidbit is usually publically-named. [They are typable.]
A tidbit can be known or unknown. A tidbit is usually unknown.
A tidbit has some text called the description.
The description of a tidbit is usually "(BUG) Tidbit lacks description."
Understand "fact" as a tidbit.
Understand "facts" as the plural of tidbit.
To mark (T - tidbit) as known: (- MarkTidbitKnown({T}); -).
To say mark (T - tidbit) as known: (- MarkTidbitKnown({T}); -).
Include (-
[ MarkTidbitKnown tid;
if (tid == nothing) {
print "(BUG) MarkTidbitKnown(", (name) tid, ")!^";
return;
}
if (~~(tid in (+ known-tidbits +) )) {
move tid to (+ known-tidbits +);
}
SetEitherOrProperty(tid, (+ known +) );
];
-).
The known-tidbits is a container.
When play begins (this is the known-tidbits container setup rule):
repeat with T running through known tidbits:
mark T as known.
Chapter - Actions
Section - Meta Actions
Abouting is an action out of world and applying to nothing.
Understand "about", "credit", "credits" as abouting.
[Carry-out rule is in hadean.ni.]
Backer-requesting is an action out of world and applying to nothing.
Understand "backers", "funders", "kickstarters" as backer-requesting.
[Carry-out rule is in hadean.ni.]
Help-requesting is an action out of world and applying to one topic.
Understand "help" as help-requesting.
Understand "help [text]" as help-requesting.
Understand the command "hint" as "help".
[Carry-out rule is in hadean.ni.]
Command-requesting is an action out of world and applying to nothing.
Understand "command", "commands" as command-requesting.
[Carry-out rule is in hadean.ni.]
Vague-restarting is an action out of world and applying to nothing.
Carry out vague-restarting:
unless there is a recallable reset-room (called R):
instead say "(BUG) There is no recallable reset-room.";
if R is not visited:
instead say "[parsermsg]You have not yet learned how to reset the world. Type [excmd]RESTART COMPLETELY[/excmd] to really start the game over from the very beginning.[/parsermsg][br]";
instead say "[parsermsg]Type [excmd]RESET[/excmd] to re-enter the void, keeping your memories. Type [excmd]RESTART COMPLETELY[/excmd] to really start the game over from the very beginning.[/parsermsg][br]";
Void-going is an action applying to nothing.
Carry out void-going:
unless there is a recallable reset-room (called R):
instead say "(BUG) There is no recallable reset-room.";
if R is not visited:
instead say "[parsermsg]You have not yet learned how to reset the world.[/parsermsg][br]";
instead try visiting R.
Understand the command "restart" as something new.
Understand "restart" as vague-restarting.
Understand "restart game/world" as vague-restarting.
Understand "restart completely/entirely/all" as restarting the game.
Understand "reset" as void-going.
Understand "reset game/world" as void-going.
Understand "reset completely/entirely/all" as restarting the game.
Understand "beginning" as void-going.
To print custom restart query (this is custom restart querying):
say "[parsermsg]Are you sure you want to completely restart the game? This will return you to the tutorial. You will forget all the rituals, formulas, and puzzle solutions you have learned. Type [excmd]YES[/excmd] if you're sure.[/parsermsg]";
To print custom restart refusal (this is custom restart refusing):
say "[parsermsg]Didn't think so.[/parsermsg]";
The custom restart the game rule is listed instead of the restart the game rule in the carry out restarting the game rulebook.
The custom restart the game rule translates into I6 as "CUSTOM_RESTART_THE_GAME_R".
Include (-
[ CUSTOM_RESTART_THE_GAME_R;
if (actor ~= player) rfalse;
( (+ custom restart querying +) -->1)();
print "^>>";
if (YesOrNo() ~= 0) {
@restart;
print "Failed.";
}
( (+ custom restart refusing +) -->1)();
new_line;
];
-).
Understand "use", "use [text]" as a mistake ("[parsermsg]The command 'use' is vague. Try a more specific action. Notes are for reading, dials are for turning, levers are for pulling, and so on.[/parsermsg]").
Understand the commands "superbrief", "short", "normal" as something new.
Understand the command "short" as "brief".
Exits-listing is an action out of world and applying to nothing.
Understand "exits" as exits-listing.
Carry out exits-listing:
let C be the can't-go of the location;
if C is "":
say you're-not-sure;
else:
say "[C][line break]".
Tutorial-toggling is an action out of world and applying to nothing.
Tutorial-on-flipping is an action out of world and applying to nothing.
Tutorial-off-flipping is an action out of world and applying to nothing.
Understand "tutorial" as tutorial-toggling.
Understand "tutorial on/yes" as tutorial-on-flipping.
Understand "tutorial off/no" as tutorial-off-flipping.
The tutorial-display is a truth state that varies. The tutorial-display is false.
[Set in the initial tutorial query rule, in the main source.]
Carry out tutorial-toggling:
if tutorial-display is false:
instead try tutorial-on-flipping;
else:
instead try tutorial-off-flipping.
Carry out tutorial-on-flipping:
if tutorial-display is true:
instead say "[parsermsg]The introductory tutorial is already on.[/parsermsg][br]";
if tutorial-phase is 99:
instead say "[parsermsg]You completed the introductory tutorial when you escaped the first room.[/parsermsg][br]";
now tutorial-display is true;
instead say "[parsermsg]Tutorial help will be displayed as you explore this room.[/parsermsg][br]";
Carry out tutorial-off-flipping:
if tutorial-display is false:
instead say "[parsermsg]The introductory tutorial is already off.[/parsermsg][br]";
now tutorial-display is false;
if tutorial-phase is 99:
instead say "[parsermsg]You completed the introductory tutorial when you escaped the first room.[/parsermsg][br]";
let was-locked be false;
if tut-initial is open:
close tut-initial; [get out of the must-LOOK-first mode]
now was-locked is true;
instead say "[parsermsg]I will stop showing tutorial help. To turn the messages back on, type [excmd]TUTORIAL ON[/excmd][period][if bool was-locked] (You probably still want to type [excmd]LOOK[/excmd][exclam-mark])[end if][/parsermsg][br]";
Understand the commands "curses", "drat", "darn", "bother" as something new.
Understand the commands "shit", "fuck", "damn" as something new.
Understand the command "sorry" as something new.
Understand "sorry" as swearing obscenely.
Section - Internal Actions
Topically-applying it to is an action applying to one visible thing and one thing.
[The noun is already off-stage.]
Check topically-applying it to when the atmosphere of the location is water-atm:
[Conveniently, potion bottles shatter in fire and vacuum, so I don't have to worry about those cases.]
instead say "You try to pour out the [short-description of the noun] over [the second noun], but it just swirls away in the water."
Report topically-applying it to:
instead say "(BUG) You topically apply [the noun] to [the second noun]."
Ingesting is an action applying to one visible thing.
[The noun is already off-stage.]
Report ingesting:
instead say "(BUG) [Generic potion ingestion of the noun], but it's not clear what happens."
Igniting it with is an action applying to one thing and one thing.
[Implicit taking and reach-checking has already occurred. The second noun is alight.]
Section - Actions at a Distance
Definition: an object is findable-or-here if it is an ever-seen recallable thing or it is in the location.
Definition: an object is findable-animate if it is an ever-seen recallable mem-character or it is an ever-seen recallable dragon.
Definition: an object is available-knowledge if it is a known formula or it is a known tidbit or it is a known recallable action-goal.
Definition: an object is findable-or-visitable-or-here if it is an ever-seen recallable thing or it is in the location or it is a recallable visited room.
[Definition: an object is findable-or-knowledge-or-here if it is a known formula or it is a known tidbit or it is a known recallable action-goal or it is an ever-seen recallable thing or it is in the location or it is a recallable visited room.]
Definition: an object is visitable-or-findable if it is a recallable visited room or it is an ever-seen recallable thing.
Understand "[any known formula]" as "[formula-spec]".
Understand "[any ever-seen recallable thing]" as "[findable-spec]".
Understand "[any recallable visited room]" as "[visitable-spec]".
Understand "[any recallable known action-goal]" as "[performable-spec]".
Understand "[any known tidbit]" as "[quizzable-spec]".
Understand "[any findable-or-here object]" as "[findable-or-here-spec]".
Understand "[any findable-animate object]" as "[findable-animate-spec]".
Understand "[any available-knowledge object]" as "[knowledge-spec]".
Understand "[any findable-or-visitable-or-here object]" as "[findable-or-visitable-or-here-spec]".
[Understand "[any findable-or-knowledge-or-here object]" as "[findable-or-knowledge-or-here-spec]".]
Understand "[any visitable-or-findable object]" as "[visitable-or-findable-spec]".
Visiting is an action applying to one visible thing.
Understand "visit [visitable-or-findable-spec]" as visiting.
Understand the commands "find", "locate" as "visit".
Understand "go to [visitable-or-findable-spec]" as visiting.
Understand "go back to [visitable-or-findable-spec]" as visiting.
Carry out visiting a room (called R):
goal-travel to R;
stop the action.
Carry out visiting a recallable mem-character (called T):
let R be the last-met-room of T;
if R is-room off-stagey:
instead say "You don't know where [the T] is.";
let V be the last-met-avatar of T;
goal-travel to R;
if the location is not R:
[Didn't make it.]
stop the action;
if V is nothing or V is no-thing or V is not in R:
say "That's odd. Where did [the T] go?";
set pronouns from V;
stop the action.
Carry out visiting a recallable thing (called T):
goal-travel to T;
set pronouns from T; [maybe we didn't make it, but set pronouns anyhow]
stop the action.
Carry out visiting:
if the noun is visible:
instead say "[The noun] [is-are noun] right here.";
else:
instead say "You're not sure how."
Numeric-visiting is an action applying to one number.
[Players shouldn't type this, although they shouldn't be able to break anything if they try.]
Understand "-visit-num [number]" as numeric-visiting.
Carry out numeric-visiting:
let N be the number understood;
let O be paranoid-object-check N;
if O is nothing:
instead say "That address ([N]) is not an object!";
if O is not a room:
instead say "That address ([N]) is not a room!";
if O is the Abstraction Layer:
instead say "That address ([N]) is not a existent room!";
say ">>[input]go to [the O][/input][command clarification break]";
[The visiting action will check the visited flag, as well as reset-rooms and so on. But we do an early check so that we're on a par with the normal "VISIT" scope. This avoids, for example, resetting the game before any reset-room is visited.]
if O is not visited:
instead say "That address ([N]) is not a visited room!";
instead try visiting O.
Creating is an action applying to one visible thing.
[As with recall, we allow "create X" for scenery in scope.]
Understand "create [findable-or-here-spec]" as creating.
Understand the commands "make", "construct", "build", "concoct", "synthesize", "synthesise", "brew" as "create".
Carry out creating a recallable mem-character (called T):
instead say "You can't create crew members."
Carry out creating a recallable thing (called T):
goal-create T;
stop the action.
Carry out creating:
if the noun is visible:
instead say "[The noun] [is-are noun] right here.";
else:
instead say "You're not sure how."
Performing is an action applying to one visible thing.
Understand "perform [performable-spec]" as performing.
Understand the commands "enact", "do" as "perform".
Carry out performing a recallable action-goal (called G):
goal-perform G;
stop the action.
Carry out performing:
instead say "You're not sure how."
Section - Returning
Returning is an action applying to nothing.
The return-room is a room that varies. The return-room is the Abstraction Layer.
The current-return-room is a room that varies. The current-return-room is the Abstraction Layer.
Understand "return" as returning.
Understand "return to [visitable-or-findable-spec]" as visiting.
Understand "go back" as returning.
Carry out returning:
if the return-room is-room off-stagey:
instead say "You haven't been anywhere yet.";
let R be the return-room;
if R is a reset-room:
now R is the near-room of R;
if R is-room off-stagey:
instead say "You're not sure how.";
if R is the location:
instead say "You haven't gone anywhere.";
say "(return to [the R])[br]";
instead try visiting R.
The last every turn rule (this is the return-room setting rule):
[We don't rely on last-visited-room because that gets updated many times per "go to X" command.]
if the current-return-room is not the location:
now the return-room is the current-return-room;
now the current-return-room is the location.
Section - Memory Actions
Recalling is an action applying to one visible thing.
[We want to permit recalling scenery which is in scope. (With a default "It's right here" message.) Checking whether it's in the location is a cheap way of doing this. It will fail for some cases, e.g. parts-of-scenery, but whatever.
A few scenery items have special recall messages. We use "check recalling" rules for those, but never for takeables or memory items.
We do *not* use the "findable-or-knowledge-or-here-spec" token. Splitting up the grammar lines (physical, then mental) gives us better disambiguation -- the parser will select a physical object if at all possible.]
Understand "recall [findable-or-visitable-or-here-spec]" as recalling.
Understand "recall [knowledge-spec]" as recalling.
Understand "recall about [findable-or-visitable-or-here-spec]" as recalling.
Understand "recall about [knowledge-spec]" as recalling.
Carry out recalling the player:
if current-tense is:
-- present-tense: say "That's not how memory works";
-- past-tense: say "That wasn't how memory worked";
-- perfect-tense: say "That's not how memory works";
-- future-tense: say "That won't be how memory works";
instead say "."
Check recalling a not recallable character:
let MC be the mem-character associated with the persona of the noun;
if MC is not nothing and MC is not the noun:
instead try recalling MC.
Carry out recalling a recallable mem-character:
if the ever-met-avatar of the noun is true:
let P be the persona of the noun;
if P is primary:
let PF be whether or not a non-shadowy character in the location persona-matches P;
say the recalled-description of the noun present PF;
say line break;
if the aspect-text-seen of the noun is:
-- 1: say "[His-Her P] shadow read: [the oc-message-basic for the noun][br]";
-- 2: say "[His-Her P] shadow read: [the oc-message-final for the noun][br]";
let R be the last-met-room of the noun;
let R2 be the last-shadow-room of the noun;
if R is-room off-stagey:
say "You don't know where [the noun] is";
unless R2 is-room off-stagey:
say ", but [his-her noun] shadow is";
if R2 is the location:
say " right here";
else:
say " [refer-preposition of R2] [refer-name of R2]";
instead say ".";
let T be the last-met-avatar of the noun;
if R is the location:
say "[The noun] is right here[if T is fracture-blocked], stuck in the fracture[end if]";
else:
say "You last saw [the noun] [refer-preposition of R] [refer-name of R][if T is fracture-blocked], caught in a fracture[end if]";
unless R2 is-room off-stagey:
say ". ([His-Her noun] shadow is";
if R2 is the location:
say " right here";
else:
say " [refer-preposition of R2] [refer-name of R2]";
instead say ".)";
instead say "."
Carry out recalling a recallable thing:
recall the noun at depth zero;
instead say "."
Carry out recalling a room:
if the noun is the location:
instead say "You're right there.";
instead say "You remember where [refer-name of noun] is[if not visited-this-cycle], although you haven't visited yet[end if]."
Carry out recalling a recallable action-goal:
if the noun is not known:
instead say you're-not-sure;
close tut-recalling-all;
instead say "[the description of the noun][line break]".
Carry out recalling a formula:
if the noun is not known:
instead say you're-not-sure;
close tut-recalling-all;
instead say "[the description of the noun][line break]".
Carry out recalling a tidbit:
if the noun is not known:
instead say you're-not-sure;
close tut-recalling-all;
instead say "[the description of the noun][line break]".
Carry out recalling:
if the noun is visible:
instead say "[The noun] [is-are noun] right here.";
else:
instead say you're-not-sure.
Visualizing is an action applying to one visible thing.
[Always redirects to recalling, except for the alien-glyphs, which are invoked directly by visualization.]
Understand "visualize [findable-or-visitable-or-here-spec]" as visualizing.
Understand "visualize [knowledge-spec]" as visualizing.
Understand "concentrate on [findable-or-visitable-or-here-spec]" as visualizing.
Understand "concentrate on [knowledge-spec]" as visualizing.
Understand "concentrate on formulas/formulae" as recalling-formulae.
Understand "concentrate on rituals" as recalling-rituals.
Understand "concentrate on facts/notes" as recalling-tidbits.
Understand "concentrate on rooms/locations/places" as recalling-rooms.
Understand "concentrate on objects/things/items" as recalling-things.
Understand "concentrate on doors/locks" as recalling-doors.
Understand the command "visualise" as "visualize".
Check visualizing a nonvocal formula:
instead try invoking the noun.
Check visualizing:
instead try recalling the noun.
Understand "where is/are/am [findable-or-visitable-or-here-spec]" as visualizing.
Understand "what is/are/am [knowledge-spec]" as visualizing.
Understand "who is/are/am [findable-animate-spec]" as visualizing.
Recalling-formulae is an action applying to nothing.
Recalling-rituals is an action applying to nothing.
Recalling-tidbits is an action applying to nothing.
Recalling-rooms is an action applying to nothing.
Recalling-things is an action applying to nothing.
Recalling-doors is an action applying to nothing.
Recalling-all is an action applying to nothing.
Understand "recall" as recalling-all.
Understand "recall formulas/formulae" as recalling-formulae.
Understand "formula", "formulas", "formulae" as recalling-formulae.
Understand "recall rituals" as recalling-rituals.
Understand "ritual", "rituals" as recalling-rituals.
Understand "recall facts/notes" as recalling-tidbits.
Understand "facts", "notes" as recalling-tidbits.
Understand "recall rooms/locations/places" as recalling-rooms.
Understand "rooms", "locations", "places" as recalling-rooms.
Understand "recall objects/things/items" as recalling-things.
Understand "objects", "things", "items" as recalling-things.
Understand "recall doors/locks" as recalling-doors.
Understand "doors", "locks" as recalling-doors.
Understand the command "think" as something new.
Understand the command "remember", "think", "consider" as "recall".
Understand "concentrate" as recalling-all.
Carry out recalling-all:
let N be the number of action-goals in known-rituals;
let M be the number of formulas in known-formulas;
let K be the number of tidbits in known-tidbits;
if (N + M + K) is greater than 40:
tutor tut-recalling-query;
if (N + M + K) is less than 60:
say "Your store of knowledge is becoming unwieldy. ";
instead say "Do you want to recall formulas, rituals, facts, places, objects, or doors?";
tutor tut-recalling-all;
if N is not zero:
follow the recalling-rituals rule;
if M is not zero:
follow the recalling-formulae rule;
if K is not zero:
follow the recalling-tidbits rule.
Carry out recalling-formulae (this is the recalling-formulae rule):
tutor tut-recalling-formulae;
say "[one of]After months of diligent practice, you have memorized[or]You know[stopping]";
say " [if less than ten formulas are in known-formulas]several common[else]an impressive list of[end if] alchemical formulae:[line break]";
list the contents of known-formulas, with newlines, indented, with extra indentation;
To say you-are-still-orienting-yourself:
if current-tense is:
-- present-tense: say "You are still orienting yourself.";
-- past-tense: say "You were still orienting yourself.";
-- perfect-tense: say "You are still orienting yourself.";
-- future-tense: say "You will still be orienting yourself."
Carry out recalling-rituals (this is the recalling-rituals rule):
let N be the number of action-goals in known-rituals;
if N is zero:
instead say you-are-still-orienting-yourself;
say "You have learned [if N is one]one ritual[else][N in words] rituals[end if]:";
if there is a not ever-done action-goal in known-rituals:
say " (* marks rituals you have not yet completed)";
say line break;
repeat with O in raw contents of known-rituals:
say "[indentation 2][O][if O is not ever-done] (*)[end if][br]";
Carry out recalling-tidbits (this is the recalling-tidbits rule):
let K be the number of tidbits in known-tidbits;
if K is zero:
instead say you-are-still-orienting-yourself;
say "You have picked up [if K is one]at least one fact[else if K is two]a couple of facts[else]assorted facts[end if]:[line break]";
list the contents of known-tidbits, using the definite article, with newlines, indented, with extra indentation;
Carry out recalling-rooms (this is the recalling-rooms rule):
unless escaped first room:
instead say "You have not yet escaped from this room.";
let R be the number of visited recallable rooms;
if R < 2:
instead say "You have escaped from the Secondary Alchemy Lab, but not explored far.";
say "Since the accident, you have visited these notable locations:[br]";
repeat with O running through visited recallable rooms:
say "[indentation 2][the O][br]";
recite the spark-unchecked rooms.
Carry out recalling-things (this is the recalling-things rule):
say "Since the accident, you have found (or created) these (portable) items:[br]";
[Yes, this is slow and there ain't nothing nobody can do about it. As a sop to efficiency we will not loop over *all things*, but over the two takeable classes separately.]
rapidly set all things not marked for listing; [loops through all things]
now the beaker is marked for listing;
now the nonexistent-stone is marked for listing;
skip certain objects for listing in recall;
if two potion-vials are ever-seen:
say "[indentation 2][group-list ever-seen unmarked for listing potion-vials][br]";
if two non-potiony chem-vials are ever-seen:
say "[indentation 2][group-list ever-seen unmarked for listing non-potiony chem-vials][br]";
if two chem-flasks are ever-seen:
say "[indentation 2][group-list ever-seen unmarked for listing chem-flasks][br]";
if two impets are ever-seen:
say "[indentation 2][group-list ever-seen unmarked for listing impets][br]";
if two metal-rods are ever-seen:
say "[indentation 2][group-list ever-seen unmarked for listing metal-rods][br]";
if two metal-wires are ever-seen:
say "[indentation 2][group-list ever-seen unmarked for listing metal-wires][br]";
if two pebbles are ever-seen:
say "[indentation 2][group-list ever-seen unmarked for listing pebbles][br]";
if two wood-splints are ever-seen:
say "[indentation 2][group-list ever-seen unmarked for listing wood-splints][br]";
if two chimes are ever-seen:
say "[indentation 2][group-list ever-seen unmarked for listing chimes][br]";
if two clay-molds are ever-seen:
say "[indentation 2][group-list ever-seen unmarked for listing clay-molds][br]";
if two metal-seals are ever-seen:
say "[indentation 2][group-list ever-seen unmarked for listing metal-seals][br]";
repeat with O running through ever-seen takeable-things:
if O is unmarked for listing:
say "[indentation 2][a O][br]";
repeat with O running through ever-seen takeable-supporters:
if O is unmarked for listing:
say "[indentation 2][a O][br]";
[Recalling-doors implementation is very game-specific, so it lives in hadean.ni.]
Vague-invoking is an action applying to nothing.
Invoking is an action applying to one visible thing.
Understand "invoke" as vague-invoking.
Understand "invoke [formula-spec]" as invoking.
Understand the commands "say", "shout", "speak", "sing" as something new.
Understand the commands "recite", "say", "shout", "speak", "chant", "sing", "intone", "vocalize", "vocalise", "pronounce" as "invoke".
Carry out vague-invoking:
tutor tut-vague-invoke;
instead say "You'll have to name the formula you want to invoke."
Carry out invoking:
instead say "(BUG) You invoke [the noun]."
Understand "examine [formula-spec]" as examining.
[Understand "examine [performable-spec]" as examining.] [Should "x fungicide" fall back to the fungicide creation ritual? Probably not, not even on a separate grammar line.]
[Some "recall" forms are defined above.]
Section - Physical Actions
Vague-entering is an action applying to nothing.
[Converted to "going inside", see above.]
Understand the command "get" as something new.
Understand "get in/on" as vague-entering.
Understand "get out/off/down/up" as exiting.
Understand "get [things]" as taking.
Understand "get in/into/on/onto/inside [something]" as entering.
Understand "get off/down/out [something]" as getting off.
Understand "get off/out of/from [something]" as getting off.
Understand "get [things inside] from [something]" as removing it from.
Understand the commands "enter", "cross" as something new.
Understand "enter" as vague-entering.
Understand "enter [something]" as entering.
Understand "cross [something]" as entering.
Understand "go out [something]" as getting off.
Understand "go out of/from [something]" as getting off.
Understand "exit [something]" as getting off.
Understand "exit from [something]" as getting off.
Understand the command "escape" as "exit".
Understand the command "out" as something new.
Understand "out" as exiting.
Understand "out of/from [something]" as getting off.
Check getting off the player:
instead say "Identity is inescapable."
Check getting off a door:
instead try entering the noun.
Understand "put [other things] through [something]" as inserting it into.
Understand "add [other things] to/into [something]" as inserting it into.
Understand "place [other things] in/inside/into [something]" as inserting it into.
Understand "place [other things] on/onto [something]" as putting it on.
Understand "place [other things] through [something]" as inserting it into.
Understand "lie on/in/inside [something]" as entering.
Understand "lay on/in/inside [something]" as entering. [yeah, yeah]
Understand "lay [other things] in/inside/into [something]" as inserting it into.
Understand "lay [other things] on/onto [something]" as putting it on.
Understand "lay down [things preferably held]" as dropping.
Understand "lay [things preferably held] down" as dropping.
Understand the command "take" as something new.
Understand "take [things]" as taking.
Understand "take off [something]" as vague-removing.
Understand "take [something] off" as vague-removing.
Understand "take [things inside] from/off [something]" as removing it from.
Understand "take inventory" as taking inventory.
Understand the command "carry", "hold" as something new.
Understand "carry [things]" as taking.
Understand "carry [things inside] from/off [something]" as removing it from.
Understand the command "hold" as "carry".
Vague-removing is an action applying to one thing.
[Redirects to taking-off for clothing; removing for contained/supported things; freeing otherwise. Do not customize.]
Understand the command "remove" as something new.
Understand "remove [something]" as vague-removing.
Understand "remove [things inside] from [something]" as removing it from.
Check vague-removing something worn:
instead try taking off the noun.
Check vague-removing something wearable:
instead try taking off the noun.
Check vague-removing something contained by a container (called C):
say "(from [the C])";
instead try removing the noun from C.
Check vague-removing something supported by a supporter (called C):
say "(from [the C])";
instead try removing the noun from C.
Check vague-removing:
instead try freeing the noun.
[The push-to action is entirely gone.]
Understand the commands "push", "shift", "move" as something new.
Understand "push [something]" as pushing.
Understand the commands "shift", "move" as "push".
Understand the command "clear" as something new. [removed from grammar]
Understand the command "press" as something new.
Understand "press [something]" as pushing.
Understand "press [something] to/on/onto/against [something]" as tapping it on.
Understand the commands "screw", "unscrew" as something new.
[Exclude setting-to meanings of "turn", which used to be available for "screw". Also parse "screw on" as simply turning, not switching-on.]
Understand "screw [something]" as turning.
Understand "screw on/off [something]" as turning.
Understand "screw [something] on/off" as turning.
Understand the command "unscrew" as "screw".
Understand the commands "rotate", "twist" as something new.
Understand "rotate [something]" as turning.
Understand "rotate [something] to [text]" as setting it to.
[Exclude setting-to meanings of "turn", which used to be available for "rotate".]
Understand the commands "twist", "spin", "crank" as "rotate".
The block setting it to rule is not listed in any rulebook.
Understand the command "align" as "set".
Understand "turn [something] to [text]" as setting it to.
Vague-setting is an action applying to one thing.
Understand "set [something]" as vague-setting.
Check vague-setting the player:
instead say "You aren't adjustable."
Report vague-setting:
say "[The noun] [is-are noun]n't a device you can set."
Check setting the player to:
instead say "You aren't adjustable."
Report setting it to:
instead say "[The noun] [is-are noun]n't a device you can set."
Understand the command "unseal" as "open".
Understand the command "seal" as "close".
Freeing is an action applying to one thing.
[Note that vague-removing can redirect here, but freeing does not have the "remove X (from container)" meaning.]
Understand "free [something]" as freeing.
Understand the commands "untie", "loose", "loosen", "unbind" as "free".
Check freeing a door:
instead try opening the noun.
Check freeing the player:
instead say "You're not sure how you're bound."
Report freeing:
if the noun is sessile:
instead say "You can't.";
else if the noun is carried:
instead say "[That-Those noun] [is-are noun]n't fastened.";
else:
instead say "[That-Those noun] [is-are noun]n't held."
Releasing is an action applying to one thing.
[Always redirects to dropping or freeing. Customize those, not releasing.]
Understand "release [something]" as releasing.
Check releasing something carried:
instead try dropping the noun.
Check releasing:
instead try freeing the noun.
Burning it with is an action applying to one thing and one thing.
Understand "burn [something] with/from/in/on [something]" as burning it with.
Understand the commands "ignite", "melt" as "burn".
The block burning rule is not listed in any rulebook.
Carry out burning:
let H be the best visible fire source besides the noun;
if H is no-thing and the noun is alight:
instead say "[The noun] is itself the only handy source of flame.";
if H is no-thing:
instead say "You lack any handy way to set [if the noun is the player]yourself[else]things[end if] on fire.";
say "([if H is sessile]in[else]with[end if] [the H])";
instead try burning the noun with H.
Check burning something with something not alight:
if the noun is alight:
instead say "[The second noun] [is-are second noun] not a source of fire, and [the noun] is already on fire anyhow.";
instead say "[The second noun] [is-are second noun] not a source of fire."
Check burning it with when the location is airless:
if the noun is the fire-sucker:
continue the action; [special case for underwater/vacuum!]
instead say "The environment is not conducive to ignition."
Check burning something alight with when the noun is the second noun:
instead say "Logically, [the noun] is already burning itself."
Carry out burning it with:
instead try igniting the noun with the second noun.
Ringing is an action applying to one thing.
[Always redirects to touching, or a failure message. (Rit-ringing comes in at a later stage.)]
Understand "ring [something]" as ringing.
Understand the command "play" as "ring".
Report ringing:
say "You're not sure how that could be done."
Check ringing a chime:
instead try touching the noun.
Check ringing the miasma-gong:
instead try touching the noun.
Understand the command "wave" as something new.
Understand "wave [something]" as waving.
Check waving the player:
instead say "You're not sure what that would look like."
Last check waving when the noun is scenery or the noun is fixed in place:
instead say "[if the noun is singular-named]It doesn't[else]They don't[end if] move."
Shaking is an action applying to one thing.
Understand "shake [something]" as shaking.
Understand the command "swing" as something new.
Understand the command "swing" as "shake".
Check shaking the player:
instead say "You shake it all about."
Last check shaking when the noun is scenery or the noun is fixed in place:
instead say "[if the noun is singular-named]It doesn't[else]They don't[end if] move."
Report shaking:
instead say "You shake [it-them noun] about, to no effect."
The report waving things rule is not listed in any rulebook.
Report waving:
instead say "You wave [it-them noun] tentatively around."
Understand the command "feel" as something new.
Understand "feel [something]" as touching.
Tapping it on is an action applying to two things.
Understand "touch [something] to/on/onto/against [something]" as tapping it on.
Understand "touch [something] with [something]" as tapping it on (with nouns reversed).
Understand the commands "tap", "poke" as "touch".
Understand the commands "tie", "attach", "fasten" as something new.
Understand "tie [something] to/on/onto [something]" as tapping it on.
Understand the commands "attach", "fasten", "bind" as "tie".
Understand "connect [something] to/onto/with [something]" as tapping it on.
Understand "apply [something] to/on/onto [something]" as tapping it on.
Understand "brush [something]" as brush-rubbing.
Understand "brush [something] to/on/onto/against [something]" as tapping it on.
Understand "brush [something] with [something]" as tapping it on (with nouns reversed).
Understand the command "clean" as something new.
Understand "clean [something]" as rubbing.
Understand "clean [something] with [something]" as tapping it on (with nouns reversed).
[Leave "dust", "shine", "polish", "sweep" with no second object (just rubbing).]
Understand the commands "rub", "scrub", "wipe" as something new.
Understand "rub [something]" as rubbing.
Understand "rub [something] to/on/onto [something]" as tapping it on.
Understand "rub [something] with [something]" as tapping it on (with nouns reversed).
Understand the commands "scrub", "scrape", "wipe" as "rub".
Brush-rubbing is an action applying to one thing.
[Always redirects to rubbing, unless you have the brush.]
Check brush-rubbing when the player carries the dispersal-brush:
say "(with [the dispersal-brush])";
instead try tapping the dispersal-brush on the noun.
Check brush-rubbing:
instead try rubbing the noun.
Check touching the player:
instead say "Not now."
Check rubbing the player:
instead say "Not now."
Instead of tapping something sessile on something not sessile (this is the tapping-sessile reversal rule):
instead try tapping the second noun on the noun.
Instead of tapping the player on:
if the second noun is the player:
instead say "Logically, you [em]are[/em] always touching yourself.";
instead try tapping the second noun on the player.
Check tapping something sessile on (this is the no-tapping-sessile rule):
if the second noun is the player:
instead try touching the noun;
instead say "You can't haul [the noun] around like that."
First check tapping something not carried on (this is the no-tapping-not-held rule):
if the noun is contained in something (called C) and C is carried:
if interrupted carrying out the implicitly taking activity with the noun:
stop the action;
say "(first removing [the noun] from [the C])";
silently try taking the noun;
if the noun is carried:
continue the action;
if the second noun is the dispersal-brush:
continue the action; [special case]
if the second noun is the player:
say "(that is, touch [the noun] to yourself)[line break]";
instead say "You aren't holding [the noun]."
First check tapping something on something alight (this is the tapping-thing-on-fire rule):
instead try burning the noun with the second noun.
First check tapping something alight on something (this is the tapping-fire-on-thing rule):
instead try burning the second noun with the noun.
First check tapping a topical chem-source on something (this is the tapping-topical-on-thing rule):
instead try putting the noun on the second noun.
Check tapping it on when the noun is the second noun:
instead say "The question of whether an entity always touches itself is food for many a late-night philosophical argument. It's not going to help you right now."
Report tapping it on:
instead say "You touch [the noun] [one of]lightly[or]carefully[or]gently[at random] to [the second noun], with no result."
Repairing is an action applying to one thing.
Understand "repair [something]" as repairing.
Understand the command "fix" as "repair".
Report repairing:
instead say "[if the noun is singular-named]That isn't[else]Those aren't[end if] obviously in need of repair."
Report repairing the player:
instead say "That's Sergeant Brooks[apostrophe] job."
Understand the commands "torture", "wreck", "thump" as something new.
Understand the command "strike" as "hit".
Smashing is an action applying to one thing.
Understand the commands "smash", "destroy", "break", "crack" as something new.
Understand "smash [something]" as smashing.
Understand the commands "crush", "destroy", "break", "crack" as "smash".
Check smashing the player:
instead try attacking the player.
Report smashing:
if the noun is scenery or the noun is fixed in place:
instead say "Unlikely.";
else:
instead say "You don't want to damage [the noun]."
The block attacking rule is not listed in any rulebook.
Check attacking:
instead say "You see no reason to start a fight with [the noun]."
Check attacking the player:
[Could modify after you've died a few times.]
instead say "After all you've survived?"
Understand the commands "inhale", "snort" as "smell".
Understand "breathe" as smelling.
Understand "breathe in" as smelling.
Understand "breathe [something]" as smelling.
Understand "breathe in [something]" as smelling.
Blowing on is an action applying to one thing.
Understand "blow [something]" as blowing on.
Understand "blow in/on/out [something]" as blowing on.
Understand "blow [something] out" as blowing on.
Understand the command "puff" as "blow".
Check blowing on a person:
instead say "Don't be crass."
Report blowing on:
say "Blowing on [the noun] is pointless."
Extinguishing is an action applying to one thing.
Understand "extinguish [something]" as extinguishing.
Understand "put out [something]" as extinguishing.
Understand "put [something] out" as extinguishing.
Understand the command "douse" as "extinguish".
Check extinguishing something alight:
instead try blowing on the noun.
[### if the player carries the fire-sucker, maybe we should be using it. Test with burning splints, kiln, but mostly the Charred Hall inferno.]
Report extinguishing the player:
instead say "You aren't on fire[if the atmosphere of the location is fire-atm], despite appearances[end if]."
Report extinguishing:
say "[if the noun is singular-named]That isn't[else]They aren't[end if] on fire."
When play begins (this is the carried noun requirement setup rule):
remove the carried noun requirement for the eating action.
Understand the command "eat" as something new.
Understand "eat [something]" as eating.
Understand the commands "drink", "swallow", "sip" as something new.
Understand the commands "drink", "swallow", "quaff" as "eat".
Understand the commands "sip", "lick" as "taste".
Check eating the player:
instead say "You're not hungry. You've never been [em]that[/em] hungry."
Emptying is an action applying to one thing.
Check emptying the player:
instead say "You aren't feeling the urge."
Last check emptying when the noun is a container (this is the general container emptying rule):
if the noun is empty:
instead say "[The noun] [is-are noun] already empty.";
if the number of things in the noun is one:
let T be the first thing held by the noun;
say "(taking [the T])";
instead try taking T;
instead say "Just take what you need."
Last check emptying when the noun is a supporter (this is the general supporter emptying rule):
if the noun is empty:
instead say "There's nothing on [the noun].";
if the number of things on the noun is one:
let T be the first thing held by the noun;
say "(taking [the T])";
instead try taking T;
instead say "Just take what you need."
Report emptying:
say "[The noun] [is-are noun]n't something you can empty."
Understand "pour [something]" as emptying.
Understand "pour out [something]" as emptying.
Understand "pour [something] out" as emptying.
Understand "pour [other things] in/inside/into [something]" as inserting it into.
Understand "pour out [other things] in/inside/into [something]" as inserting it into.
Understand "pour [other things] on/onto/over [something]" as putting it on.
Understand "pour out [other things] on/onto/over [something]" as putting it on.
Understand the command "empty", "spill", "dump" as "pour".
Understand "discharge [something]" as emptying.
Understand "discharge [other things] in/inside/into [something]" as inserting it into.
Understand "discharge [other things] on/onto/at/over [something]" as putting it on.
Understand the commands "vent", "decant", "sprinkle" as "discharge".
Understand "set [other things] in/inside/into [something]" as inserting it into.
Understand "set [other things] on/onto [something]" as putting it on.
Understand "fill [something] with/from [something]" as inserting it into (with nouns reversed).
Understand the command "scale" as something new.
Understand "scale [something]" as climbing.
Understand "climb down [something]" as climbing.
Understand "climb in/inside/into/on/onto/through [something]" as entering.
Understand "climb out [something]" as getting off.
Understand "climb out of [something]" as getting off.
Check inserting something into an open door:
instead say "Flinging things through open doors would be messy."
Instead of putting the player on something sessile (this is the put-me is entering rule):
instead try entering the second noun.
Instead of inserting the player into something sessile (this is the insert-me is entering rule):
instead try entering the second noun.
Instead of putting something on something alight (this is the put-on-fire rule):
instead try burning the noun with the second noun.
Instead of inserting something into something alight (this is the insert-in-fire rule):
instead try burning the noun with the second noun.
Understand the command "feed" as something new.
Understand "feed [other things] to/in/inside/into [something]" as inserting it into.
Understand the command "consult" as something new.
Dir-looking is an action out of world applying to one thing.
Check dir-looking:
if the noun is not a direction:
instead say "(BUG) Dir-looking [noun], which is not a direction.";
[We could check "the door [noun] from the location" but the results are inconsistent and unsatisfying.]
instead say "[parsermsg]This game does not permit you to look into adjacent rooms. Try going [noun] and seeing what you find.[/parsermsg][br]".
[I don't know why I have to define this grammar token in I6. You'd think "look [direction]" would work, but it breaks the "look" grammar.]
[Since we're defining this, we take the opportunity to ignore "in/out" directions.]
The Understand token direction-spec translates into I6 as "DirectionSpecToken".
Include (-
[ DirectionSpecToken wd obj;
wd = NextWord();
objectloop (obj in Compass) {
if (obj == in_obj or out_obj)
continue;
if (WordInProperty(wd, obj, name))
return obj;
}
return GPR_FAIL;
];
-).
Understand the command "look", "l" as something new.
Understand "look" as looking.
Understand "look [direction-spec]" as dir-looking.
Understand "look around" as looking.
Understand "look at [something]" as examining.
Understand "look at [something] in/with/through [something]" as inspecting it with.
Understand "look inside/in/into/within/through/on [something]" as searching.
Understand "look inside/in/into/within/through [something] at [something]" as inspecting it with (with nouns reversed).
Understand "look under [something]" as looking under.
Understand "look out/outside" as look-outward-ing.
Understand "look out/outside [something]" as searching.
Understand the command "l" as "look".
Understand the command "peer" as "look".
Understand "swabbie", "apprentice", "ensign", "forsyth" as yourself.
The description of the player is "Not the most promising Ensign in His Majesty's Navy."
Check examining a direction (this is the new examine directions rule):
instead try dir-looking the noun.
Inspecting it with is an action applying to one visible thing and one thing.
Understand "examine [something] in/with/through [something]" as inspecting it with.
Understand the command "inspect" as "examine".
Understand "view [something]" as examining.
[Omit "view formula", though]
Understand "view [something] in/with/through [something]" as inspecting it with.
A thing has some text called the lens-view. [for the planetary lens]
Check inspecting a direction with (this is the inspect directions with rule):
instead try dir-looking the noun.
Check inspecting it with when the noun is the second noun (this is the reflexive inspection rule):
instead say "You can't inspect [the noun] with itself."
Report inspecting it with:
instead say "You can't look at things through [the second noun]."
Reading is an action applying to one visible thing and requiring light.
[Generally this should either redirect to "examine" or be blocked.]
A thing can be readable.
The readable property translates into I6 as "attr_extra_readable".
Definition: an object is readable if I6 routine "CheckAttrExtraReadable" says so (hack).
Understand the command "read" as something new.
Understand "read [something]" as reading.
Understand "read [something] with/through [something]" as inspecting it with.
Check reading a readable thing:
instead try examining the noun.
Check reading:
instead say "There's nothing to read there."
Look-outward-ing is an action applying to nothing.
[Redirects to "examine outside" unless a room customizes it (to look out a window).]
Check look-outward-ing:
instead try examining outside.
[ The singing action is gone.
The block singing rule is not listed in any rulebook.
Check singing:
if the atmosphere of the location is water-atm:
instead say "You have no talent for underwater singing.";
if the atmosphere of the location is vacuum-atm:
instead say "You can't sing; there's no air.";
instead say "You have no talent for singing."
]
Understand "jump out/off/down/up" as exiting.
Understand "jump in/into/on/onto/inside [something]" as entering.
Understand "jump off [something]" as getting off.
Understand "jump off/out of/from [something]" as getting off.
Understand the command "skip" as something new. [Drop this as a "jump" synonym.]
The block jumping rule is not listed in any rulebook.
Check jumping:
if the atmosphere of the location is water-atm:
instead try going up;
if the atmosphere of the location is vacuum-atm:
instead say "You jump up and down. The gravity feels roughly normal, at least.";
instead say "You jump up and down for a bit."
The block sleeping rule is not listed in any rulebook.
Check sleeping:
instead say "You aren't at all tired."
The block waking up rule is not listed in any rulebook.
Check waking up:
instead say "This may be a nightmare, but it is real."
Understand the commands "buy", "purchase" as something new. [removed from grammar]
Chapter - The Characters
A persona is a kind of value. The plural of persona is personae.
No-persona is a persona.
The Ensign is a persona. [Only used for self-imitation.]
The Sergeant is a persona. [Only used for attempts to recall (which will fail).]
The Grafter is a persona.
The Climber is a persona.
The Scholar is a persona.
The Captain is a persona.
Definition: a persona is primary if it is Captain or it is Climber or it is Grafter or it is Scholar.
Definition: a persona is high-rank if it is Captain or it is Climber or it is Grafter.
A character is a kind of thing.
A character has a persona.
A character is always fixed in place.
Include (- has animate -) when defining a character.
A character can be fracture-blocked.
A character can be female or male.
A character is usually proper-named.
The printed name of a character is usually "[persona of the item described]".
The remote-name of a character is usually "[persona of the item described]".
Understand "person", "figure", "marchman" as a character.
The verb to persona-match (it persona-matches, they persona-match, it is persona-matching) implies the persona property.
To say he-she (P - persona):
if P is Captain or P is Grafter:
say "she";
else:
say "he".
To say He-She (P - persona):
if P is Captain or P is Grafter:
say "She";
else:
say "He".
To say his-her (P - persona):
if P is Captain or P is Grafter:
say "her";
else:
say "his".
To say His-Her (P - persona):
if P is Captain or P is Grafter:
say "Her";
else:
say "His".
To say him-her (P - persona):
if P is Captain or P is Grafter:
say "her";
else:
say "him".
To say he-she (C - character):
if C is a shadow-character:
say "it";
else:
say he-she persona of C.
To say He-She (C - character):
if C is a shadow-character:
say "It";
else:
say He-She persona of C.
To say his-her (C - character):
if C is a shadow-character:
say "its";
else:
say his-her persona of C.
To say His-Her (C - character):
if C is a shadow-character:
say "Its";
else:
say His-Her persona of C.
To say him-her (C - character):
if C is a shadow-character:
say "it";
else:
say him-her persona of C.
Section - Base Character Rules
Check searching a character:
instead say "That's not really possible when [his-her noun] clothing is as rigid as ice."
Check inspecting a character with the planetary-lens:
instead say "You peer at [the noun] through the lens. [He-She noun] has Gaian associations, as human beings always do. The image is oddly distant, though."
Check inspecting a character with the oculus:
say "You peer through the oculus, and see the complex mesh of elements that makes up a human body.[para]";
instead try examining the noun.
Check touching a character:
let C be the noun;
instead say "Although [he-she C] is no longer fracture-blocked, [he-she C] feels like a statue -- not stone, but hard and utterly still. It's as if [he-she C] exists within an imperceptible layer of altered time."
Check rubbing a character:
instead try touching the noun.
Check taking a character:
instead say "[The noun] cannot be moved."
Check pushing a character:
instead try taking the noun.
Check pulling a character:
instead try taking the noun.
Check turning a character:
instead try taking the noun.
Check listening to a character:
instead say "[The noun] is silent."
Check freeing a character:
instead say "You don't know what's wrong with [him-her noun]."
Check waking a character:
instead try freeing the noun.
Check inserting something not sessile into a character:
if the noun is topical:
continue the action;
instead say "[The second noun] is in no state to swallow."
Check attacking a character:
let P be the persona of the noun;
if P is Captain:
instead say "The very thought makes your soul curl up and whimper.";
if P is high-rank:
instead say "It's not that you've never thought about clouting an officer, but this is not the time. For several reasons.";
instead say "You've never been the type for donnybrooks with the other apprentices. Anyway, this is not the time, for several reasons."
Check cutting a character:
instead try attacking the noun.
Check kissing a character:
instead say "The Navy frowns on such informality."
Check tasting a character:
instead try kissing the noun.
Check squeezing a character:
instead try kissing the noun.
Section - Fracture-Blocked (Base) Characters
Instead of doing anything except examining or searching or recalling to a fracture-blocked character (this is the fracture-blocked character out of reach rule):
if inspecting a character with something:
continue the action;
instead say "[He-She noun] is behind the fracture, out of reach."
Check putting something on a fracture-blocked character:
instead try touching the second noun.
Check inserting something into a fracture-blocked character:
instead try touching the second noun.
Check tapping something on a fracture-blocked character:
instead try touching the second noun.
Check searching a fracture-blocked character:
instead try examining the noun.
Section - Shadow Characters
A shadow-character is a kind of character.
A shadow-character is usually not proper-named.
A shadow-character can be neuter. A shadow-character is always neuter.
The printed name of a shadow-character is usually "shadow of [persona of the item described]".
Understand "shadow", "shadow of", "faint", "trailing" as a shadow-character.
Definition: a character is shadowy rather than non-shadowy if it is a shadow-character.
To move-and-shadow (NC - character) to (NR - room) with (SC - shadow-character) and (OC - character):
if OC is fracture-blocked:
now SC is fracture-blocked;
else:
now SC is not fracture-blocked;
move NC to NR;
let OR be the location of OC;
now OC is off-stage;
if OR is-room off-stagey:
say "(BUG) move-and-shadow: [OC] was off-stage.";
else:
now SC is in OR;
[We retain the incorrect memory of the avatar location, but we wipe the memory of the shadow location. It's inconvenient to maintain that as a separate mistake.]
let MC be the mem-character associated with the persona of SC;
if MC is not nothing:
now the last-shadow-room of MC is the Abstraction Layer.
The initial appearance of a shadow-character is usually "[meet item described][persona of the item described] has vanished. Only a shadow remains[if the item described is fracture-blocked] within the fracture[end if]."
The description of a shadow-character is usually "You see a faint trailing shadow where [persona of the item described] was standing."
Instead of doing anything except examining or searching or recalling to a shadow-character (this is the shadow-character untouchable rule):
if inspecting a character with something:
continue the action;
if entering a character:
instead say "This isn't a play.";
instead say "The shadow is intangible."
Check putting something on a shadow-character:
instead try touching the second noun.
Check inserting something into a shadow-character:
instead try touching the second noun.
Check tapping something on a shadow-character:
instead try touching the second noun.
Check searching a shadow-character:
instead say "As far as you can tell, it's just a shadow."
Check inspecting a shadow-character with the planetary-lens:
instead say "You peer at [the noun]. It doesn't seem to be visible through the lens at all."
Check inspecting a shadow-character with the oculus:
let P be the persona of the noun;
let MC be the mem-character associated with P;
if MC is nothing:
instead say "(BUG) [The noun] has no mem-character.";
if the story-resolution of MC is no-persona:
say "[one of]This is very strange. Through the oculus you do not see a shadow, but[or]Again, strangely, the oculus renders the shadow in[stopping] words:[para]";
if the aspect-text-seen of MC < 1:
now the aspect-text-seen of MC is 1;
instead say the oc-message-basic for MC;
else:
if the aspect-text-seen of MC is 1:
say "The shadow forms words when viewed through the oculus. But the text is longer than before:[para]";
else:
say "The shadow forms words when viewed through the oculus:[para]";
if the aspect-text-seen of MC < 2:
now the aspect-text-seen of MC is 2;
instead say the oc-message-final for MC.
The Sha-Captain is a shadow-character. The persona of Sha-Captain is Captain.
The Sha-Scholar is a shadow-character. The persona of Sha-Scholar is Scholar.
The Sha-Grafter is a shadow-character. The persona of Sha-Grafter is Grafter.
The Sha-Climber is a shadow-character. The persona of Sha-Climber is Climber.
Section - Recallable Characters
A mem-character is a kind of character.
A mem-character is usually recallable.
A mem-character is usually scenery.
A mem-character has a room called last-met-room. The last-met-room of a mem-character is usually the Abstraction Layer. [reset if you meet a shadow and discover the avatar gone]
A mem-character has a room called last-shadow-room. The last-shadow-room of a mem-character is usually the Abstraction Layer.
A mem-character has a thing called last-met-avatar. The last-met-avatar of a mem-character is usually no-thing.
A mem-character has a truth state called ever-met-avatar. The ever-met-avatar of a mem-character is usually false. [once set, always set]
A mem-character has a persona called the story-resolution. The story-resolution of a mem-character is usually no-persona.
A mem-character can be aspect-positive or aspect-negative.
A mem-character can be aspect-endorsed or aspect-reproached. A mem-character is usually aspect-endorsed.
A mem-character has a number called the aspect-text-seen. [0: never oculused a shadow; 1: oculused a shadow before resolution; 2: after resolution]
[Understanding lines are in hadean.ni.]
Mem-Captain is a female mem-character. The persona of Mem-Captain is Captain.
Mem-Scholar is a male mem-character. The persona of Mem-Scholar is Scholar.
Mem-Grafter is a female mem-character. The persona of Mem-Grafter is Grafter.
Mem-Climber is a male mem-character. The persona of Mem-Climber is Climber.
Mem-Sergeant is a male mem-character. The persona of Mem-Sergeant is Sergeant.
To decide what mem-character is the mem-character associated with (P - persona):
if P is:
-- Captain: decide on Mem-Captain;
-- Scholar: decide on Mem-Scholar;
-- Grafter: decide on Mem-Grafter;
-- Climber: decide on Mem-Climber;
really decide on nothing.
To say meet (C - character):
let P be the persona of C;
let MC be the mem-character associated with P;
[I am blowing off the possibility that you complete chapter 1 and encounter a shadow without first seeing its ch1 avatar.]
now the ever-met-avatar of MC is true;
now C is ever-seen;
now MC is ever-seen;
if C is a shadow-character:
now the last-shadow-room of MC is the location of C;
if the last-met-room of MC is the location of C:
now the last-met-avatar of MC is no-thing;
now the last-met-room of MC is Abstraction Layer;
else:
now the last-met-avatar of MC is C;
now the last-met-room of MC is the location of C.
To decide what persona is the resolution of (P - persona):
let MC be the mem-character associated with P;
if MC is nothing:
decide on no-persona;
decide on the story-resolution of MC.
To decide what number is the aspect-text-seen for (P - persona):
let MC be the mem-character associated with P;
if MC is nothing:
decide on 0;
decide on the aspect-text-seen of MC.
Definition: a persona (called P) is aspect-positive:
let MC be the mem-character associated with P;
if MC is nothing:
decide no;
if MC is aspect-positive:
decide yes.
Definition: a persona (called P) is aspect-negative:
let MC be the mem-character associated with P;
if MC is nothing:
decide yes;
if MC is aspect-negative:
decide yes.
To flip the first aspect of (P - persona):
let MC be the mem-character associated with P;
if MC is nothing:
stop;
if MC is aspect-negative:
now MC is aspect-positive;
else:
now MC is aspect-negative.
Definition: a persona (called P) is aspect-endorsed:
let MC be the mem-character associated with P;
if MC is nothing:
decide no;
if MC is aspect-endorsed:
decide yes.
Definition: a persona (called P) is aspect-reproached:
let MC be the mem-character associated with P;
if MC is nothing:
decide yes;
if MC is aspect-reproached:
decide yes.
To flip the second aspect of (P - persona):
let MC be the mem-character associated with P;
if MC is nothing:
stop;
if MC is aspect-reproached:
now MC is aspect-endorsed;
else:
now MC is aspect-reproached.
To resolve story of (P1 - persona) towards (P2 - persona):
let MC be the mem-character associated with P1;
if MC is nothing:
say "(BUG) Resolving story of [P1], but no mem-char.";
stop;
if the story-resolution of MC is not no-persona:
say "(BUG) Resolving story of [P1], but it is already [story-resolution of MC].";
now the story-resolution of MC is P2.
Mem-Captain is ever-seen. [At startup.]
Mem-Sergeant is ever-seen. [At startup. But we'll never meet him.]
Chapter - How About a Little Fire, Scarecrow
[A thing can be alight.] [Defined earlier to catch an attribute slot.]
A thing has a number called the flame-point.
The verb to burn at (it burns at, they burn at, it is burning at) implies the flame-point property.
[For efficiency, we declare that the only fire-consumable items are wood-splints.]
A wood-splint is a kind of takeable-thing.
A wood-splint has a number called the burn-life.
A wood-splint has a number called the max-burn-life.
[Definition: a thing is flammable if the flame-point of it is greater than zero.
Definition: a thing is nonflammable if the flame-point of it is not greater than zero.]
Definition: a wood-splint is fire-consumable if the max-burn-life of it is greater than zero.
To decide what thing is the best visible fire source besides (ignore - thing):
let result be no-thing;
let temp be zero;
[It's actually important that we check "alight" before "quick-visible" here. The QV code chokes on multilocated things like doors and backdrops. (Do not create a flaming door.)]
repeat with T running through alight quick-visible things:
if T is not ignore and the flame-point of T is greater than temp:
now temp is the flame-point of T;
now result is T;
decide on result.
To decide whether currently fireproof:
if fire-potion-remaining is greater than zero:
decide yes.
Check igniting the player with something when currently fireproof:
if the second noun is el-fire:
instead say "You're not willing to test the efficacy of fire resistance against elemental fire. Not with your own flesh, anyhow.";
if the atmosphere of the location is fire-atm:
instead say "You're already completely enveloped in fire.";
if the second noun is swamp-pith:
instead say "You stick your finger in the flame. You can't feel it at all.";
instead say "You stick your finger in the flame. It's just a little warm."
Check igniting the player with something:
if the second noun is el-fire:
instead say "Elemental fire would consume your flesh instantly.[first time][br][em]Hands off the pure elementals, swabbie. No marchmen will melt themselves in my classroom.[/em][br][only]";
if the second noun is linden:
instead say "You wave your finger through the flame. And again -- ow. Well, it's still fire, but weaker than even a candle-flame; you can [em]nearly[/em] hold your finger in it.";
if the second noun is swamp-pith:
instead say "You wave your finger through the pith flame. It's hot, but not burning-hot. How strange.";
instead say "You think about setting yourself on fire, and decide not to."
Check igniting something alight with something (this is the generic already-alight rule):
instead say "[The noun] [is-are noun] already alight."
Report igniting it with:
say "Randomly setting things on fire won't help."
To say general-contact-ignite:
if the player carries the second noun:
say "You hold [the second noun] to [the noun]";
else:
say "You hold [the noun] to [the second noun]".
Check blowing on something alight:
instead say "The flame only flickers."
Check touching something alight:
instead try igniting the player with the noun.
Section - The Fire-Consumption Daemon
["now the burn-life of T is the max-burn-life of T" -- this is handled by the initial world reset.]
The fire-consumption count is a number that varies.
To update fire consumption:
now the fire-consumption count is the number of alight fire-consumable wood-splints.
Every turn when the fire-consumption count is greater than zero (this is the fire-consumption daemon rule):
let change-count be zero;
repeat with T running through alight fire-consumable wood-splints:
decrement the burn-life of T;
let N be the burn-life of T;
if N is:
-- 0:
now T is not alight; [so that splinters are not named as "burning splinters"]
if the player carries T:
say "You drop [the T] as it burns down to nothing[if not currently fireproof]. Ouch[end if].";
else if T is visible:
say "[The T] has burned away entirely.";
increment change-count;
retire T by burning out;
-- 1:
if T is visible:
say "[The T] is nearly gone.";
-- 3:
if T is visible:
say "[The T] is getting very short.";
-- 6:
if T is visible:
say "[The T] is noticeably smaller.";
if change-count is greater than zero:
update fire consumption.
Section - The Fire-Resistance Daemon
The fire-potion-remaining is a number that varies. [resettable]
Every turn (this is the fire-resistance daemon rule):
if fire-potion-remaining is greater than zero:
decrement fire-potion-remaining;
if fire-potion-remaining is:
-- 6:
if the atmosphere of the location is fire-atm:
say "The flames licking against your skin feel warmer now.";
-- 4: say "Your fingers begin to buzz with returning circulation.";
-- 2:
if the atmosphere of the location is fire-atm:
say "The air is distinctly hot now.";
-- 1:
say "Your fingers are tingling";
if the atmosphere of the location is fire-atm:
say ", and the flames are becoming painfully hot. It might be time to retreat";
say ".";
-- 0:
if the atmosphere of the location is not fire-atm:
if not goal-achieving:
say "Your fingers are no longer tingling. The potion must have worn off.";
else:
say "The fire-resistance potion has worn off.";
else:
say "Your fingers are no longer tingling. Instead, they're burning, along with the rest of you. Your dissolution is brief but extremely unpleasant.";
invoke reset, involuntarily.
Section - The Camphrost Daemon
Every turn when the holder of the camphrost is not nothing (this is the camphrost daemon rule):
decrement the vapor-life of the camphrost;
if the camphrost is in the crock and the crock is closed:
increment the vapor-pressure of the crock;
if the vapor-pressure of the crock is greater than 2 and the blackwood is in the crock and the blackwood is alight:
perform camphrost flashover;
continue the action;
if the vapor-life of the camphrost is:
-- 9:
if the player carries the camphrost or the camphrost is visible:
say "Wisps of blue vapor steam from the camphrost";
say extra camphrost note;
say ".";
-- 6:
if the player carries the camphrost or the camphrost is visible:
say "The lump of camphrost is shrinking visibly";
say extra camphrost note;
say ".";
-- 2:
if the player carries the camphrost or the camphrost is visible:
say "The camphrost is nearly gone";
say extra camphrost note;
say ".";
-- 0:
if the player carries the camphrost or the camphrost is visible:
say "The bit of camphrost has sublimed entirely away";
say extra camphrost note;
say ".";
retire the camphrost with explanation "The lump of camphrost sublimated away";
To say extra camphrost note:
if the camphrost is in the crock:
if the crock is open:
say ". The vapor drifts from the open crock";
else:
say ". The vapor accumulates in the crock"
To perform camphrost flashover:
say "The blackwood flares up. Then, with a violent hiss and an electric-blue flash, the camphrost vapor ignites.";
now the vapor-pressure of the crock is zero;
now the crock is shifted;
perform crock incineration.
The camphrost-flare is scenery. The printed name is "camphrost flare".
[Used only in the crock incineration routine. Not referrable to.]
The flame-point is 35.
Section - Kindlology
To derive the kindling of (T - thing) from (F - thing):
if T is not a mixing-container:
say "(BUG) Tried to derive kindling of random thing [T] from [F].";
stop;
now the mixture-result is no-subst;
try subst-kindling T from F;
if the mixture-result is no-subst:
stop;
now T comprises the mixture-result;
fix up the substance of T.
Subst-kindling it from is an action applying to two visible things.
Check subst-kindling:
if the second noun is not alight:
instead say "(BUG) Subst-kindling, but [the second noun] is not alight."
Carry out subst-kindling:
follow the kindle-processing rules.
Kindle-processing is a rulebook.
Rule for kindle-processing when the noun is the reservoir and noun comprises nickel-oil-subst and the second noun is el-fire:
unless rstate is active and rstate bestates RSChymicStart and rstate is entension-word-used:
dephlogisticate the second noun;
if the nickel-wire is in the retort:
retire the nickel-wire by ritual-or-alchemy;
if rstate is active:
now rstate bestates RSFailed;
now the reservoir comprises brown-paste-subst;
fix up the substance of the reservoir;
instead say "The nickel filings glow red. Then orange, then yellow -- and then the oil ignites, an ugly boil of smoke that splatters molten nickel across the inside of the retort.[para]When the smoke clears, the oil has been reduced to a greasy brown paste, and the [base-description of the second noun] rod is extinguished.";
unless (the retort contains exactly the second noun) or (the retort contains exactly the nickel-wire and the second noun):
dephlogisticate the second noun;
if the nickel-wire is in the retort:
retire the nickel-wire by ritual-or-alchemy;
if rstate is active:
now rstate bestates RSFailed;
now the reservoir comprises brown-paste-subst;
fix up the substance of the reservoir;
instead say "The nickel filings glow red -- then orange, then yellow. You wince, expecting the oil to ignite at any moment; but it does not. Instead, the nickel slowly liquifies into a shining metal pool. The oil shimmers and ripples above it.[para]White smoke rises within the retort. No, that's not right -- your extra additions must be throwing off the balance of the distillation. Nothing condenses out, anyhow. In moments the [base-description of the second noun] rod is extinguished, lying in a pool of greasy brown paste.";
now the player carries the second noun;
now the fire-source-used of sublime-creation is the second noun;
dephlogisticate the second noun;
if the nickel-wire is in the retort:
retire the nickel-wire by ritual;
mark the sublime-creation as done;
shut down the ritual state;
shut down the retort;
now the player carries the sublime;
set pronouns from the sublime;
instead say "The nickel filings glow red -- then orange, then yellow. You wince, expecting the oil to ignite at any moment; but it does not. Instead, the nickel slowly liquifies into a shining metal pool. The oil shimmers and ripples above it.[para]Pale vapors rise within the retort -- the volatile fractions of the oil. They condense on the inner surface of the glass. Minute droplets gather and flow downwards. When they reach the release valve, you tap the sublime spirit into a fresh vial.[para]When you have extracted all the fractions you need, you pull the dump lever. The greasy remains of the oil and nickel are washed away. The [base-description of the second noun] rod -- dephlogisticated and cool now -- falls into your hand."
Rule for kindle-processing when the noun is the reservoir and noun comprises mineral-oil-subst and the second noun is el-fire and the nickel-wire is in the retort:
unless rstate is active and rstate bestates RSChymicStart and rstate is entension-word-used:
dephlogisticate the second noun;
retire the nickel-wire by ritual-or-alchemy;
if rstate is active:
now rstate bestates RSFailed;
now the reservoir comprises brown-paste-subst;
fix up the substance of the reservoir;
instead say "The nickel glows red where the elemental flame touches it. Then orange, then yellow -- and then the oil ignites, an ugly boil of smoke that splatters molten nickel across the inside of the retort.[para]When the smoke clears, the oil has been reduced to a greasy brown paste, and the [base-description of the second noun] rod is extinguished.";
unless the retort contains exactly the nickel-wire and the second noun:
dephlogisticate the second noun;
retire the nickel-wire by ritual-or-alchemy;
if rstate is active:
now rstate bestates RSFailed;
now the reservoir comprises brown-paste-subst;
fix up the substance of the reservoir;
instead say "The nickel glows red where the elemental flame touches it -- then orange, then yellow. You wince, expecting the oil to ignite at any moment; but it does not. Instead, the nickel slowly liquifies into a shining metal pool. The oil shimmers and ripples above it.[para]White smoke rises within the retort. No, that's not right -- your extra additions must be throwing off the balance of the distillation. Nothing condenses out, anyhow. In moments the [base-description of the second noun] rod is extinguished, lying in a pool of greasy brown paste.";
now the player carries the second noun;
now the fire-source-used of sublime-creation is the second noun;
dephlogisticate the second noun;
retire the nickel-wire by ritual;
mark the sublime-creation as done;
shut down the ritual state;
shut down the retort;
now the player carries the sublime;
set pronouns from the sublime;
instead say "The nickel glows red where the elemental flame touches it -- then orange, then yellow. You wince, expecting the oil to ignite at any moment; but it does not. Instead, the nickel slowly liquifies into a shining metal pool. The oil shimmers and ripples above it.[para]Pale vapors rise within the retort -- the volatile fractions of the oil. They condense on the inner surface of the glass. Minute droplets gather and flow downwards. When they reach the release valve, you tap the sublime spirit into a fresh vial.[para]When you have extracted all the fractions you need, you pull the dump lever. The greasy remains of the oil and nickel are washed away. The [base-description of the second noun] rod -- dephlogisticated and cool now -- falls into your hand."
Rule for kindle-processing when the noun is the reservoir and noun comprises ori-muriatic-subst and the second noun is the burner and the heating-time of the reservoir >= 4:
increment the heating-time of the reservoir;
if the heating-time of the reservoir is:
-- 5: instead say "The green acid solution is noticeably reducing in volume.";
-- 6: instead say "The green acid is now a thick pool in the bottom of the reservoir.";
now the mixture-result is calcinate-crystal-subst;
instead say "The green acid thickens to a paste, and then rapidly dries, leaving a residue of coarse, dark-green crystals."
Rule for kindle-processing when the noun is the reservoir and noun comprises ori-muriatic-2-subst and the second noun is the burner and the heating-time of the reservoir >= 2:
increment the heating-time of the reservoir;
if the heating-time of the reservoir is:
-- 3: instead say "The viridian acid solution is noticeably reducing in volume.";
-- 4: instead say "The viridian acid is now a thick pool in the bottom of the reservoir.";
unless the retort contains exactly nothing:
now the mixture-result is unknown-subst;
instead say "The viridian solution turns to an unpleasant murky olive -- no doubt the result of contamination.";
unless rstate is active and at RSPercalcinateTempered:
now the mixture-result is unknown-subst;
instead say "Something precipitates out of the viridian solution, turning it to an unpleasant murky olive. The ritual balance must have been disrupted.";
mark the percalcinate-creation as done;
shut down the ritual state;
shut down the retort;
now the player carries the percalcinate;
set pronouns from the percalcinate;
instead say "The viridian acid thickens to a paste, and then rapidly dries, leaving a residue of green-gold powder. This must be your percalcinate. You extract it into a fresh vial, and switch off the gas flames."
Rule for kindle-processing when the noun is the reservoir and noun comprises muriatic-subst and the second noun is the burner and the orichalcum is in the retort and the heating-time of the reservoir >= 3:
now the mixture-result is ori-muriatic-subst;
retire the orichalcum by ritual-or-alchemy;
now the heating-time of the reservoir is 3; [control timing]
instead say "The orichalcum slowly dissolves into the acid, lending it a lovely grass-green tint."
Rule for kindle-processing when the noun is the reservoir and noun comprises vitriolic-subst and the second noun is the burner and the orichalcum is in the retort and the heating-time of the reservoir >= 3:
now the mixture-result is ori-vitriol-subst;
retire the orichalcum by ritual-or-alchemy;
instead say "The orichalcum slowly dissolves into the acid, lending it a lovely sky-blue tint."
Rule for kindle-processing when the noun is the reservoir and noun comprises vitriolic-subst and the second noun is the burner and the fluorite is in the retort and the heating-time of the reservoir >= 3:
now the mixture-result is fluor-vitriol-subst;
retire the fluorite by ritual-or-alchemy;
instead say "The fluorspar crystal slowly dissolves into the acid, giving it a rich amber tint."
Rule for kindle-processing when the noun is the reservoir and noun comprises violet-mix-subst and the second noun is the burner and the retort contains exactly el-earth and at RSGaianAlumed and the heating-time of the reservoir >= 2:
retire the el-earth by ritual;
mark Gaian-precip-creation as done;
shut down the ritual state;
shut down the retort;
now the player carries the Gaian-precip;
set pronouns from the Gaian-precip;
instead say "The elemental earth dissolves. The violet solution boils more vigorously, now releasing a thick cloud of steam.[para]Slowly, the solution is reduced, growing darker and more opaque. You coddle the gas valve as it thickens. After several careful moments, you have dried the solution to a purple-grey dust. Excellent. You shut off the heat, and tap the Gaian precipitate from the retort into a fresh vial."
Rule for kindle-processing when the noun is the reservoir and noun comprises indigo-mix-subst and the second noun is the burner and the retort contains exactly el-earth and at RSCounterGaianAlumed and the heating-time of the reservoir >= 2:
retire the el-earth by ritual;
mark counter-Gaian-precip-creation as done;
shut down the ritual state;
shut down the retort;
now the player carries the counter-Gaian-precip;
set pronouns from the counter-Gaian-precip;
instead say "The elemental earth dissolves. The indigo solution boils more vigorously, now releasing a thick cloud of steam.[para]Slowly, the solution is reduced, growing darker and more opaque. You coddle the gas valve as it thickens. After several careful moments, you have dried the solution to a indigo-blue dust. Excellent. You shut off the heat, and tap the counter-Gaian precipitate from the retort into a fresh vial."
Rule for kindle-processing when the noun is the reservoir and noun comprises violet-mix-subst and the second noun is the burner and the retort contains exactly perfect-diamond and at RSGaianAlumed and the heating-time of the reservoir >= 2:
retire the perfect-diamond by ritual;
now rstate bestates RSFailed;
instead say "The diamond dissolves. The violet solution boils more vigorously, now releasing a thick cloud of steam.[para]After a few moments, the steam dies away. The solution does not appear to be reducing."
Rule for kindle-processing when the noun is the reservoir and noun comprises indigo-mix-subst and the second noun is the burner and the retort contains exactly perfect-diamond and at RSCounterGaianAlumed and the heating-time of the reservoir >= 2:
retire the perfect-diamond by ritual;
now rstate bestates RSFailed;
instead say "The diamond dissolves. The indigo solution boils more vigorously, now releasing a thick cloud of steam.[para]After a few moments, the steam dies away. The solution does not appear to be reducing."
Rule for kindle-processing when the noun is the reservoir and the noun comprises lubanja-subst:
now the mixture-result is clear-subst;
instead say "The spirit erupts in a burst of blue flame, which rapidly burns down until the volatile fractions have been consumed."
Rule for kindle-processing when the noun is the reservoir and the noun comprises alcohol-subst:
now the mixture-result is clear-subst;
instead say "There's a (startling but satisfying) [em]poof.[/em] Blue flames dance on the surface for a few moments, until too much alcohol burns off to sustain them."
Rule for kindle-processing when the noun comprises lubanja-subst:
say "You dip [the second noun] into [the noun]";
let M be the substance of the noun;
now the mixture-result is clear-subst;
instead say ". The spirit erupts in a burst of blue flame, which rapidly burns down until the volatile fractions have been consumed.";
Rule for kindle-processing when the noun comprises alcohol-subst:
say "You dip [the second noun] into [the noun]";
let M be the substance of the noun;
now the mixture-result is clear-subst;
instead say ". There's a (startling but satisfying) [em]poof.[/em] Blue flames dance on the surface for a few moments, until too much alcohol burns off to sustain them.";
Rule for kindle-processing when the noun is the reservoir and noun comprises layered-subst and the second noun is el-fire:
now the mixture-result is unknown-subst;
instead say "The mixture bubbles furiously, but the elemental fire is not extinguished. The liquid layers break apart in the turbulence, however."
Rule for kindle-processing when the noun is the reservoir and noun comprises layered-subst and the second noun is the burner and the heating-time of the reservoir > 2:
now the mixture-result is unknown-subst;
instead say "The mixture begins to simmer, and the liquid layers break apart in the turbulence."
Rule for kindle-processing when noun comprises layered-subst and the second noun is el-fire:
say "You dip [the second noun] into the liquid";
now the mixture-result is unknown-subst;
instead say ". It bubbles furiously, but the elemental fire is not extinguished. The liquid layers break apart in the turbulence, however."
Rule for kindle-processing when the noun is the reservoir and noun comprises mineral-oil-subst and the second noun is el-fire:
now the mixture-result is brown-paste-subst;
instead say "The oil spatters and smokes furiously around [the second noun]. The oil doesn't quite ignite, but gradually the elemental heat reduces it to a thick brown consistency."
Rule for kindle-processing when noun comprises mineral-oil-subst and the second noun is el-fire:
say "You dip [the second noun] into the oil";
now the mixture-result is brown-paste-subst;
instead say ", which spatters and smokes furiously. The oil doesn't quite ignite, but gradually the elemental heat reduces it to a thick brown consistency."
Rule for kindle-processing when the noun is the reservoir and noun comprises nickel-oil-subst and the second noun is el-fire:
now the mixture-result is brown-paste-subst;
instead say "The oil spatters and smokes furiously around [the second noun]. The oil doesn't quite ignite, but gradually the elemental heat reduces it to a thick brown consistency."
Rule for kindle-processing when noun comprises nickel-oil-subst and the second noun is el-fire:
say "You dip [the second noun] into the oil";
now the mixture-result is brown-paste-subst;
instead say ", which spatters and smokes furiously. The oil doesn't quite ignite, but gradually the elemental heat reduces it to a thick brown consistency."
Rule for kindle-processing when the noun is the reservoir and the second noun is el-fire:
let M be the substance of the noun;
if M is powdery:
instead say "The elemental fire crackles in the powder, but is not extinguished.";
if M is pasty:
instead say "The elemental fire crackles in the [generic term for M], but is not extinguished.";
instead say "The [if M is unknown-subst][M] bubble[else][M] bubbles[end if] furiously, but the elemental fire is not extinguished."
Rule for kindle-processing when the second noun is el-fire:
let M be the substance of the noun;
say "You dip [the second noun] into the [generic term for M]";
if M is powdery:
instead say ". The elemental fire crackles, but is not extinguished.";
if M is pasty:
instead say ". The elemental fire crackles, but is not extinguished.";
instead say ". It bubbles furiously, but the elemental fire is not extinguished."
Rule for kindle-processing when the second noun is the burner:
if the noun is not the reservoir:
instead say "(BUG) Kindle rule tried to heat [the noun] with the gas burner.";
increment the heating-time of the reservoir;
instead follow the general-reservoir-heating rule.
Rule for kindle-processing when the noun is the reservoir:
let M be the substance of the noun;
now the second noun is not alight;
update fire consumption;
instead say "The [M] has extinguished [the second noun]."
The last kindle-processing rule:
let M be the substance of the noun;
say "You dip [the second noun] into the [generic term for M]";
now the second noun is not alight;
update fire consumption;
instead say ", but it just extinguishes the flame."
This is the general-reservoir-heating rule:
let M be the substance of the noun;
let H be the heating-time of the reservoir;
if M is pasty:
if H > 3:
instead say "The gas flame heats the [M], which simmers thickly.";
instead say "The gas flame heats the [M].";
if M is powdery:
instead say "The gas flame heats the [M].";
if M is unknown-subst:
if H > 2:
instead say "The [M] simmer quietly over the flame.";
instead say "The gas flame heats the [M].";
if M is mineral-oil-subst:
if H > 6:
instead say "The [M] simmers quietly, and smokes a bit.";
if H > 3:
instead say "The [M] simmers quietly over the flame.";
instead say "The gas flame heats the [M].";
if M is a substance-type:
if H > 5:
instead say "The [M] boils vigorously.";
if H > 2:
instead say "The [M] bubbles over the flame.";
instead say "The gas flame heats the [M].";
instead say "(BUG) General-reservoir-heating should not get here ([M])."
Section - Enkilning Rules
The enkilning source is a thing that varies. The enkilning source is no-thing.
The enkilning rulebook is an object-based rulebook.
Rule for enkilning a low-melting-rod metal-rod (called T):
say "[The T] immediately slumps into a puddle, and dribbles away into the kiln.";
rule fails.
Rule for enkilning a low-melting-wire metal-wire (called T):
say "[The T] immediately melts into droplets, and dribbles away into the kiln.";
rule fails.
Rule for enkilning rutilum-seal:
say "Rutilum melts at, what, three thousand degrees? This kiln won't do it.";
rule succeeds.
Rule for enkilning a metal-seal (called T):
say "[The T] immediately slumps into a puddle, and dribbles away into the kiln.";
rule fails.
Rule for enkilning the mercury:
say "The mercury bubbles in the heat, and soon boils away. (You hope the kiln has good exhaust ventilation.)";
rule fails.
Rule for enkilning a dried-vegetable thing (called T):
say "[The T] flares up and falls to aromatic ash.";
rule fails.
Rule for enkilning the mushroom:
say "The mushroom doesn't exactly burn, but it quickly crumbles to ash.";
rule fails.
Rule for enkilning the coral:
say "The coral doesn't exactly burn, but it quickly crumbles to ash.";
rule fails.
Rule for enkilning a feather-or-feather thing:
say "The feather doesn't exactly burn, but it quickly crumbles to ash.";
rule fails.
Rule for enkilning the silk-cord:
say "The silk burns away, though not quickly.";
rule fails.
Rule for enkilning the dirty scalpel:
say "Whatever's on the scalpel only seems to be baking on there more firmly."
Rule for enkilning the rock-salt:
now the rock-salt is not moist;
rule succeeds.
Rule for enkilning the camphrost:
say "The camphrost explodes in a puff of blue vapor.";
rule fails.
Rule for enkilning el-water:
say "The capsule shatters, spraying elemental water into steam.";
rule fails.
Rule for enkilning el-fire:
rule succeeds.
Rule for enkilning phlo-gold:
if the phlo-gold is alight:
say "The gold doesn't seem to burn any faster in the kiln than it already was.";
else:
say "The phlogisticated gold does not ignite. Elemental fire is devilishly difficult to ignite."
Rule for enkilning phlo-electrum:
if the phlo-electrum is alight:
say "The electrum doesn't seem to burn any faster in the kiln than it already was.";
else:
say "The phlogisticated electrum does not ignite. Elemental fire is devilishly difficult to ignite."
Rule for enkilning a bubble (called T):
if T is empty:
say "The fragile bubble shatters in the heat.";
else:
say "The charged bubble bursts in the heat. The elemental air's ripple is lost in the heat-ripple of the kiln.";
rule fails.
Rule for enkilning fire-sucker:
say "The bottle cracks in the heat; the crimson fire-devourer spills into the kiln. There is a mighty [em]whump[/em] as the interior of the kiln goes dark.[para]However, you have not extinguished the flames beneath, and the fire-brick retains most of its heat. The kiln's red glow returns within moments.";
rule fails.
Rule for enkilning fire-resistance:
say "The bottle cracks in the heat; the potion of fire resistance boils uselessly away. (Apparently just because it makes you resistant to fire, that doesn't mean it is.)";
rule fails.
Rule for enkilning a potion-vial (called T):
say "The bottle cracks in the heat; the potion of [short-description of T] boils uselessly away.";
rule fails.
Rule for enkilning brun-oil:
say "The vial cracks in the heat; the [brun-oil-subst] explodes into a tiny orange fireball.";
rule fails.
Rule for enkilning sublime:
say "The vial cracks in the heat; the [sublime-subst] explodes into a tiny blue fireball.";
rule fails.
Rule for enkilning perfect-mud:
say "The vial cracks in the heat; the [perfect-mud-subst] dries out and falls to dust.";
rule fails.
Rule for enkilning mineral-oil:
say "The flask cracks in the heat; the [mineral-oil-subst] spills into the kiln and burns away in a smear of yellow flame.";
rule fails.
Rule for enkilning alcohol:
say "The flask cracks in the heat; the [alcohol-subst] spills into the kiln and explodes in a brief blue fireball.";
rule fails.
Rule for enkilning lubanja:
say "The flask cracks in the heat; the [lubanja-subst] spills into the kiln and explodes in a brief blue fireball.";
rule fails.
Rule for enkilning a chem-source (called T):
say "The [if T is a chem-flask]flask[else]vial[end if] cracks in the heat";
let M be the substance of T;
if M is acidic:
say "; the [M] boils away into acrid steam.";
else if M is powdery:
say "; the [M] scatters uselessly across the kiln.";
else:
say "; the [M] boils away.";
rule fails.
Rule for enkilning a wood-splint (called T):
let temp be the flame-point of the enkilning source;
if temp < ignition-point of T:
if T is not alight:
say "[The T] lies inertly, unaffected by the heat.";
else if temp >= vaporization-point of T:
say "[The T] flares up in the heat and is instantly consumed.";
now T is not alight;
rule fails;
else if T is not alight:
say "[The T] quickly bursts into flame.";
now T is alight;
update fire consumption.
Rule for enkilning the torch-lighter:
say "The torch-lighter explodes in a tiny yellow fireball.";
rule fails.
Section - Incinerating Rules
The incinerating rulebook is an object-based rulebook.
The incinerating rulebook has outcomes inert subject (failure - the default), ignite subject, vaporize subject, melt subject, burn subject, shatter subject, explode subject, boil subject, extinguish subject.
The ignite-bucket is an abstraction-bucket.
The short-description is "catches fire". The short-description-multi is "catch fire".
The extinguish-bucket is an abstraction-bucket.
The short-description is "is extinguished". The short-description-multi is "are extinguished".
The vaporize-bucket is an abstraction-bucket.
The short-description is "vaporizes". The short-description-multi is "vaporize".
The melt-bucket is an abstraction-bucket.
The short-description is "melts". The short-description-multi is "melt".
The boil-bucket is an abstraction-bucket.
The short-description is "boils away". The short-description-multi is "boil away".
The shatter-bucket is an abstraction-bucket.
The short-description is "shatters". The short-description-multi is "shatter".
The explode-bucket is an abstraction-bucket.
The short-description is "explodes". The short-description-multi is "explode".
The burn-bucket is an abstraction-bucket.
The short-description is "burns up". The short-description-multi is "burn up".
To incinerate (T - thing):
follow the incinerating rulebook for T;
if the outcome of the rulebook is no-outcome:
stop;
if the outcome of the rulebook is:
-- inert subject outcome: do nothing;
-- ignite subject outcome: now T is in the ignite-bucket;
-- vaporize subject outcome: now T is in the vaporize-bucket;
-- melt subject outcome: now T is in the melt-bucket;
-- burn subject outcome: now T is in the burn-bucket;
-- shatter subject outcome: now T is in the shatter-bucket;
-- explode subject outcome: now T is in the explode-bucket;
-- boil subject outcome: now T is in the boil-bucket;
-- extinguish subject outcome: now T is in the extinguish-bucket;
-- otherwise: say "(BUG) Incinerate failure for [T].";
To perform inventory incineration in (source - thing):
now the enkilning source is the source;
repeat with T in raw contents of the player:
incinerate T;
update fire consumption;
if there is a non-empty abstraction-buckets:
say "[line break]Unfortunately, your possessions do not fare so well. In the heat";
recite the buckets;
now the enkilning source is no-thing;
repeat with T in raw contents of the ignite-bucket:
now the player carries T;
repeat with B running through all abstraction-buckets:
repeat with T in raw contents of B:
now T retired to incinerated-fate;
now T retired with source;
now T is off-stage;
sanity-check the empty buckets.
To perform crock incineration:
now the enkilning source is the camphrost-flare;
repeat with T in raw contents of the crock:
incinerate T;
update fire consumption;
if the phlo-gold is in the ignite-bucket:
now the phlo-gold is in the crock;
mark the gold-ignition as done;
say "[line break]The light swirls around the phlogisticated gold, like innumerable fireflies drawn to something greater. You hear a distinct basso [em]pop[/em] as the metal bursts into flame -- the lambent gold aura of elemental fire.";
if there is a non-empty abstraction-buckets:
say "[line break]In the brief flare";
recite the buckets;
now the enkilning source is no-thing;
repeat with T in raw contents of the ignite-bucket:
now T is in the crock;
repeat with T in raw contents of the extinguish-bucket:
now T is in the crock;
repeat with B running through all abstraction-buckets:
repeat with T in raw contents of B:
now T retired to incinerated-fate;
now T retired with camphrost-flare;
now T is off-stage;
sanity-check the empty buckets.
Rule for incinerating a low-melting-rod metal-rod:
melt subject.
Rule for incinerating a low-melting-wire metal-wire:
melt subject.
Rule for incinerating the rutilum-seal:
inert subject.
Rule for incinerating a metal-seal:
melt subject.
Rule for incinerating the mercury:
boil subject.
Rule for incinerating the silk-cord:
burn subject.
Rule for incinerating a dried-vegetable thing:
burn subject.
Rule for incinerating the mushroom:
burn subject.
Rule for incinerating the coral:
burn subject.
Rule for incinerating a feather-or-feather thing:
burn subject.
Rule for incinerating the camphrost:
vaporize subject.
Rule for incinerating a bubble:
shatter subject.
Rule for incinerating a chem-vial:
explode subject.
Rule for incinerating a chem-flask:
shatter subject.
Rule for incinerating el-water:
explode subject.
Rule for incinerating the blackwood when the enkilning source is the camphrost-flare:
now the blackwood is not alight;
extinguish subject.
Rule for incinerating a wood-splint (called T):
let temp be the flame-point of the enkilning source;
if temp < ignition-point of T:
inert subject;
else if temp >= vaporization-point of T:
now T is not alight;
vaporize subject;
else if T is not alight:
now T is alight;
ignite subject.
Rule for incinerating the rock-salt:
now the rock-salt is not moist;
inert subject.
Rule for incinerating the not alight phlo-gold when the enkilning source is the camphrost-flare:
now the phlo-gold is alight;
ignite subject.
Rule for incinerating the phlo-electrum when the enkilning source is the camphrost-flare:
now the phlo-electrum is not alight;
melt subject.
Rule for incinerating the torch-lighter:
shatter subject.
Section - The Kiln
The kiln is a recallable scenery container.
Understand "massive", "towering", "stack", "edifice", "brick", "firebrick", "interior", "cavity", "red", "glow", "heat", "narrow", "opening" as the kiln.
The lens-view of the kiln is "the bowels of the Earth".
Check examining the kiln:
say "The kiln is a towering stack of firebrick. You can see gas burners roaring behind gaps in the base, pouring heat into the mass. Above, a narrow opening reveals the kiln's interior. The cavity shows no open flame, only a red glow and a thick ripple of heated air.";
instead try searching the kiln.
Check searching the kiln:
let N be the number of things in the kiln;
if N is zero:
say "The kiln is empty";
else if N is one:
say "Within the kiln's fury, you see [a first thing held by the kiln roomily]";
else:
say "The kiln contains [a list of things *in the kiln roomily]";
[### should show supported items in both cases]
instead say "."
Check switching on the kiln:
instead try switching on the kiln-burner.
Check switching off the kiln:
instead try switching off the kiln-burner.
Check extinguishing the kiln:
instead try switching off the kiln-burner.
Check repairing the kiln:
instead try repairing the kiln-burner.
Check touching the kiln when currently fireproof:
instead say "You lay your hand on the firebrick. It feels warmish."
Check touching the kiln:
instead say "[one of]You brush the firebrick with your finger. As you might expect, it's scorchingly hot, and you spend a moment waving your hand around and swearing[or]It's still scorchingly hot[stopping]."
Check smelling the kiln:
instead say "The kiln smells of hot brick."
Check pushing the kiln:
instead try touching the kiln.
Check pulling the kiln:
instead try touching the kiln.
Check taking the kiln:
if not currently fireproof:
say "Even if it weren't blazingly hot, it";
else:
say "It";
instead say " weighs tons."
Check entering the kiln:
if currently fireproof:
instead say "Sure, you're fireproof, but the kiln isn't large enough to climb into.";
instead say "You have no desire to incinerate yourself."
The insert-stuff-in-kiln rule is listed after the better can't insert what's not held rule in the check inserting it into rulebook.
Check inserting something takeable into the kiln (this is the insert-stuff-in-kiln rule):
if currently fireproof:
mark kiln-reach-goal as done;
say "You slide [the noun] unhurriedly into the kiln.";
else:
say "You push [the noun] into the kiln's heat; but you have to yank your hand away instantly.";
now the noun is in the kiln;
now the enkilning source is the kiln-burner;
follow the enkilning rulebook for the noun without suppressing breaks;
if rule failed:
retire the noun by burning in the kiln;
now the enkilning source is no-thing;
stop the action.
The put-stuff-on-supporters-in-kiln rule is listed after the better can't put what's not held rule in the check putting it on rulebook.
Check putting something takeable on a portable supporter when the second noun is in the kiln (this is the put-stuff-on-supporters-in-kiln rule):
if currently fireproof:
mark kiln-reach-goal as done;
say "You slide [the noun] unhurriedly onto [the second noun].";
else:
say "You push [the noun] onto [the second noun], amid the heat; but you have to yank your hand away instantly.";
if the second noun is a clay-mold and the second noun is empty:
let F be the file of the second noun;
if the noun is a low-melting-wire metal-wire or the noun is a low-melting-rod metal-rod or the noun is a low-melting-seal metal-seal:
let M be the seal-metal associated with the noun;
let T be the seal form of M with F;
if T is no-thing:
retire the noun vaguely;
instead say "(BUG) [The noun] melts into nothing.";
retire the noun by transformation into T;
now T is on the second noun;
set pronouns from T;
instead say "[line break]The [smetal of T] melts immediately, filling the [file of T] File mold.";
now the noun is on the second noun;
now the enkilning source is the kiln-burner;
follow the enkilning rulebook for the noun without suppressing breaks;
if rule failed:
retire the noun by burning in the kiln;
now the enkilning source is no-thing;
stop the action.
Rule for reaching inside the kiln when not currently fireproof:
if putting something on and the second noun is a portable supporter and the second noun is in the kiln:
allow access;
if inserting something into and the second noun is a portable supporter and the second noun is in the kiln:
allow access;
say "You can barely come near the kiln's opening. Reaching inside is impossible.";
deny access.
Rule for reaching inside the kiln when currently fireproof:
mark kiln-reach-goal as done;
allow access;
Check blowing on something when the noun is in the kiln:
instead say "Blowing on something inside the furnace-hot kiln is pointless."
The kiln-burner is a plural-named scenery thing. The printed name is "gas burners".
The description is "Gaps in the kiln's base reveal a row of gas burners, all blazing furiously. There is a gas valve set into the floor nearby."
The kiln-burner is alight. It burns at 15.
Understand "fire", "flame", "gas", "burner", "burners", "gap", "gaps", "base", "valve" as the kiln-burner.
Check switching on the kiln-burner:
instead say "The gas burners are already alight."
Check switching off the kiln-burner:
instead say "[one of]You twist the gas valve, but it seems to be stuck[or]You grip the gas valve as hard as you can, but it won't budge[stopping]."
Check turning the kiln-burner:
instead try switching off the kiln-burner.
Check pushing the kiln-burner:
instead try switching off the kiln-burner.
Check pulling the kiln-burner:
instead try switching off the kiln-burner.
Check extinguishing the kiln-burner:
instead try switching off the kiln-burner.
Check vague-setting the kiln-burner:
instead try switching off the kiln-burner.
Check freeing the kiln-burner:
instead try switching off the kiln-burner.
Check repairing the kiln-burner:
instead say "You're not sure how to unstick the gas valve."
Check blowing on the kiln-burner:
instead say "One of the gas flames flickers a bit."
Check smelling the kiln-burner:
instead try smelling the kiln.
Check attacking the kiln-burner:
instead say "You bang on the gas valve, but it doesn't loosen."
Check smashing the kiln-burner:
instead say "You bang on the gas valve, but it doesn't loosen."
Instead of putting the mineral-oil on the kiln-burner:
instead say "Despite the stories, oil doesn't magically unstick everything."
Section - Vapor Crock
The crock is a recallable glassy scenery transparent open openable container. The printed name is "vapor crock".
Understand "vapor", "wide", "glass", "vapor-ware", "vaporware", "cylinder", "lid", "McGrew", "McGrew's" as the crock.
The crock has a number called the vapor-pressure.
The crock can be shifted. [smell of burning; resettable]
Understand "pale", "blue" as the crock when vapor-pressure of the crock is not zero.
Check examining the crock:
say "A McGrew Crock is a piece of vapor-ware; it allows you to submerge items in a controlled atmosphere or aitheric medium. It's a wide glass cylinder, a foot wide and two feet high, with a gasketted lid.[para]";
instead try searching the crock.
Check searching the crock:
if the crock is empty:
if the crock is open:
say "The crock is empty; its lid is standing open";
else:
say "The crock is sealed but empty";
if the vapor-pressure of the crock is not zero:
if the vapor-pressure of the crock is less than 3:
say ", except for a thin, pale blue vapor";
else:
say ", except for a dense, pale blue vapor";
else:
if the crock is open:
say "The crock's lid is standing open";
else:
say "The crock is sealed";
say ". You see [a list of things *in the crock roomily] within";
if the vapor-pressure of the crock is not zero:
if the vapor-pressure of the crock is less than 3:
say ".[para]A pale blue vapor is rising in the crock";
else:
say ".[para]A pale blue vapor swirls densely in the crock";
instead say "."
Check opening the closed crock:
say "You unseal and open the lid";
if the vapor-pressure of the crock is not zero:
now the vapor-pressure of the crock is zero;
say ". The blue vapor spills out and dissipates";
now the crock is open;
if the crock is shifted:
say ". A remnant scorched aroma drifts out";
now the crock is not shifted;
instead say "."
Report closing the crock:
instead say "You close the crock and seal its lid."
Check inspecting the crock with the oculus:
instead say "Through the oculus, the vapor crock shows traces of sublimation and ignition."
Chapter - Vacuum Work
The vacuum-potion-remaining is a number that varies. [resettable]
The vacuumizing rulebook is an object-based rulebook.
The vacuumizing rulebook has outcomes inert subject (failure - the default), extinguish subject, vaporize subject, shatter subject, explode subject, boil subject.
To vacuumize (T - thing):
follow the vacuumizing rulebook for T;
if the outcome of the rulebook is no-outcome:
stop;
if the outcome of the rulebook is:
-- inert subject outcome: do nothing;
-- extinguish subject outcome: now T is in the extinguish-bucket;
-- vaporize subject outcome: now T is in the vaporize-bucket;
-- shatter subject outcome: now T is in the shatter-bucket;
-- explode subject outcome: now T is in the explode-bucket;
-- boil subject outcome: now T is in the boil-bucket;
-- otherwise: say "(BUG) Vacuumize failure for [T].";
To perform inventory vacuumization in (dest - room):
repeat with T in raw contents of the player:
vacuumize T;
update fire consumption;
if there is a non-empty abstraction-bucket:
say "[line break]Unfortunately, your possessions do not fare so well. In the vacuum";
recite the buckets;
repeat with T in raw contents of the extinguish-bucket:
now the player carries T;
repeat with B running through all abstraction-buckets:
repeat with T in raw contents of B:
now T retired to vacuum-fate;
now T retired with dest;
now T is off-stage;
sanity-check the empty buckets.
[We assume that all containers and supporters, including takeable-supporters, and also the player, are vacuum-stable.]
To recursively vacuumize (T - thing):
if T is the player:
repeat with T2 running through things carried by the player:
vacuumize T2;
stop;
if T is a container:
repeat with T2 running through things in T:
recursively vacuumize T2;
if T is a supporter:
repeat with T2 running through things on T:
recursively vacuumize T2;
if T is takeable:
vacuumize T.
To perform room vacuumization in (dest - room):
[Not using the fast contents iteration, because this is recursive.]
repeat with T running through things in dest:
recursively vacuumize T;
if there is a non-empty abstraction-bucket:
say "[line break]Unfortunately, your possessions do not fare so well. In the vacuum";
recite the buckets;
[This always returns extinguished splints to the player, even if they were on the floor. Oh well.]
repeat with T in raw contents of the extinguish-bucket:
now the player carries T;
repeat with B running through all abstraction-buckets:
repeat with T in raw contents of B:
now T retired to vacuum-fate;
now T retired with dest;
now T is off-stage;
sanity-check the empty buckets.
Rule for vacuumizing a charged bubble:
explode subject.
Rule for vacuumizing el-water:
shatter subject.
Rule for vacuumizing the lubanja:
boil subject.
Rule for vacuumizing the sublime:
boil subject.
Rule for vacuumizing the polar-oil:
[alien technology]
inert subject.
Rule for vacuumizing the aither-protection:
[why punish the player at this point?]
inert subject.
Rule for vacuumizing a potion-vial:
shatter subject.
Rule for vacuumizing a chem-source (called T):
let M be the substance of T;
if M is powdery:
inert subject;
if M is water-based:
boil subject;
if M is acidic:
boil subject;
Rule for vacuumizing an alight wood-splint (called T):
now T is not alight;
extinguish subject.
Rule for vacuumizing alight phlo-gold:
now the phlo-gold is not alight;
extinguish subject.
Rule for vacuumizing alight phlo-electrum:
now the phlo-electrum is not alight;
extinguish subject.
Rule for vacuumizing the torch-lighter:
shatter subject.
Rule for vacuumizing the camphrost:
vaporize subject.
Rule for vacuumizing the rock-salt:
now the rock-salt is not moist;
inert subject.
Rule for vacuumizing the mushroom:
now the mushroom is not moist;
inert subject.
Rule for vacuumizing the honeysuckle:
now the honeysuckle is not moist;
inert subject.
Rule for vacuumizing the pinecone:
now the pinecone is not moist;
inert subject.
Chapter - Alien Aither
The aither-potion-remaining is a number that varies. [resettable]
A room can be alien-aither-env.
Every turn when the location is alien-aither-env (this is the aither daemon rule):
if aither-potion-remaining is zero:
say "The ache in your bones becomes worse -- horribly worse -- and the lights go dim and red. Or a dim red vapor is bleeding into the world. Perhaps your sight is failing. Perhaps everything else is.";
invoke reset, involuntarily;
else:
mark aither-survival-goal as done.
Chapter - Underwater
[A thing can be moist.]
[To save space, moist is defined per-object: pinecone, mushroom, honeysuckle, rock-salt.]
The moisturizing rulebook is an object-based rulebook.
The moisturizing rulebook has outcomes inert subject (failure - the default), extinguish subject, dissolve subject.
The dissolve-bucket is an abstraction-bucket.
The short-description is "dissolves". The short-description-multi is "dissolve".
To moisturize (T - thing):
follow the moisturizing rulebook for T;
if the outcome of the rulebook is no-outcome:
stop;
if the outcome of the rulebook is:
-- inert subject outcome: do nothing;
-- extinguish subject outcome: now T is in the extinguish-bucket;
-- dissolve subject outcome: now T is in the dissolve-bucket;
-- otherwise: say "(BUG) Moisturize failure for [T].";
To perform inventory moisturization in (dest - room):
repeat with T in raw contents of the player:
moisturize T;
update fire consumption;
let spoken be false;
if the extinguish-bucket is non-empty:
now all things in the extinguish-bucket are not alight;
say "[line break]Your plunge has doused ";
list the contents of the extinguish-bucket, tersely, as a sentence, using the definite article;
now spoken is true;
repeat with T in raw contents of the extinguish-bucket:
now the player carries T;
let N be the number of el-fire things carried by the player;
if N is not zero:
if spoken is false:
say "[line break]Elemental fire burns underwater, it seems";
else:
say ". Elemental fire burns underwater, however";
if N is one:
let T be a random el-fire thing carried by the player;
say "; the [short-description of T] rod bubbles and sputters away";
else:
say "; the phlogisticated rods bubble and sputter away";
say " furiously";
now spoken is true;
if there is a non-empty abstraction-bucket:
if spoken is false:
say "[line break]In the water";
else:
say ".[para]On top of that";
recite the buckets;
repeat with B running through all abstraction-buckets:
repeat with T in raw contents of B:
now T retired to water-fate;
now T retired with dest;
now T is off-stage;
now spoken is false;
if spoken is true:
say ".";
sanity-check the empty buckets.
To perform throw moisturization with (T - thing) in (dest - room):
moisturize T;
update fire consumption;
if T is in the extinguish-bucket:
now T is not alight;
say "[The T] falls into the water and is doused";
now T is in dest;
else if T is in an abstraction-bucket:
say "In the water";
recite the buckets, omitting final period;
now T retired to water-fate;
now T retired with dest;
now T is off-stage;
else if T is el-fire:
say "Elemental fire burns underwater, it seems";
say "; the [short-description of T] rod bubbles and sputters as it sinks";
now T is in dest;
else:
say "[The T] [if T is singular-named]falls[else]fall[end if] into the water and [if T is singular-named]sinks[else]sink[end if]";
now T is in dest;
say ".";
sanity-check the empty buckets.
Rule for moisturizing an alight wood-splint (called T):
now T is not alight;
extinguish subject.
Rule for moisturizing the pinecone:
now the pinecone is moist;
inert subject.
Rule for moisturizing the mushroom:
now the mushroom is moist;
inert subject.
Rule for moisturizing the honeysuckle:
now the honeysuckle is moist;
inert subject.
Rule for moisturizing the rock-salt:
now the rock-salt is moist;
inert subject.
Rule for moisturizing the zafranum:
dissolve subject.
Rule for moisturizing the camphrost:
dissolve subject.
Rule for moisturizing the torch-lighter:
now the torch-lighter is not alight;
inert subject.
Section - Breath-Holding
The breath-remaining is a number that varies. [resettable]
The breath-potion-remaining is a number that varies. [resettable]
To begin underwater activity:
say "You[if breath-potion-remaining is zero] take a deep breath and[end if] jump into the chilly water";
if breath-potion-remaining is greater than zero:
say ". The potion [one of]seems to be[or]is still[stopping] working -- you feel no urge to breathe";
[good thing we can't go from vacuum to water, or vice versa]
now breath-remaining is seven;
say "."
To cease underwater activity:
if breath-potion-remaining is greater than zero or breath-remaining is greater than four:
say "You pull yourself out of the water.";
else if breath-remaining is greater than two:
say "You break the surface, blow out breath, and pull yourself from the water.";
else if breath-remaining is not zero:
say "You break the surface, suck in a gasp of air, and pull yourself from the water.";
else: