"The Table" by Matt Weiner Include Undo Output Control by Erik Temple. Include Basic Screen Effects by Emily Short. Section - Preliminaries Attic is a room. [We'll never use this.] Instead of looking: stop the action. [Prevents the room name from printing out at the beginning of the game.] Report undoing an action: [Prevents the room name from printing after undoing.] say "[bracket]Previous turn undone.[close bracket][line break]"; rule succeeds. When play begins: say "[help text]"; now the left hand status line is "The Table"; now the right hand status line is "M. Weiner". Helping is an action applying to nothing. Understand "help" or "hint" or "hints" or "instructions" as helping. Carry out helping: say "[help text]" Crediting is an action applying to nothing. Understand "credit" or "credits" as crediting. Carry out crediting: say "[credit text]" Abouting is an action applying to nothing. Understand "about" as abouting. Carry out abouting: say "[help text][line break][credit text]" To say help text: say "To interact, type single words. Almost any major word that appears in the text will be somehow understood. Other words, including traditional IF commands, will yield more unpredictable results. UNDO, RESTART, SAVE, RESTORE, and QUIT work as usual.[line break][line break]To see these instructions again, type HELP, HINT, or INSTRUCTIONS. To see credits and acknowledgments, type CREDITS. To see both, type ABOUT." To say credit text: say "'The Table' was written by Matt Weiner for the IF Demo Fair. It uses the extensions Basic Screen Effects by Emily Short and Undo Output Control by Erik Temple, and includes code written by Victor Gijsbers and Juhana Leitonen, as well as a suggestion by EmacsUser. Andrew Plotkin's 'The Space Under The Window' and Aaron Reed's 'Experiment One' were important inspirations. [line break][line break]Thanks to all of the above, for the posters at intfiction.org for more helpful suggestions, to the Inform development team, and to Emily again for organizing the IF Demo Fair." After printing the banner text: say "[line break]every night in the attic scratching away at the old wooden table[line break]" A theme is a kind of thing. A theme has a table-name called transition-table. The transition-table of a theme is usually the Table of Miscellaneous Transitions. ["Transition" because they're usually printed on the way from the starting theme to the ending theme. If we were printing different quips when the theme was the very last one to be triggered in a turn, we'd need a different set of tables for that.] Use no scoring, American dialect, and the serial comma. [I almost left out no scoring; I don't think those ever come up, but I insist on them anyway.] To say rp: say "[run paragraph on]". [Defining a random member of a list of things:] To decide what thing is a random member of (target list - a list of things): let N be the number of entries in target list; let M be a random number between 1 and N; decide on entry M of target list. Section - Themes [The themes are the topics that organize our navigation through the various things we can print.] The table is a theme. The transition-table of the table is the Table of Table Transitions. Notebook is a theme. Understand "spiral" as the notebook. The transition-table of the notebook is the Table of Notebook Transitions. Age is a theme. The transition-table of age is the Table of Age Transitions. The house is a theme. The transition-table of the house is the Table of House Transitions. Light is a theme. The transition-table of light is the Table of Light Transitions. Writing is a theme. The transition-table of writing is the Table of Writing Transitions. World is a theme. The transition-table of world is the Table of World Transitions. Memory is a theme. The transition-table of memory is the Table of Memory Transitions. [When we've printed the last quip for a theme a certain number of times, we end the story. The end-count keeps track of how many times we've printed the last quip; the end-cap keeps track of how many times we're allowed to.] Every theme has a number called the end-count. The end-count of a theme is usually 0. Every theme has a number called the end-cap. The end-cap of a theme is usually 3. The end-cap of age is 6. The end-cap of the notebook is 2. The end-cap of the house is 2. The end-cap of light is 2. The end-cap of the world is 2. The end-cap of memory is 2. Definition: a theme is finished if its end-count is at least its end-cap. [We want to link basically every word that appears in a quip to some theme.] Understand "wooden/wood/table's/cold/where/solid/more" as the table. Understand "flat/soft/cardboard/paper/away/spiral/notebooks/cover/shaded/shade/pencil/scribbled/scribble/over/fading/fade/faded/together/inside/pages/page/gray/grey" as the notebook. Understand "old/now/left/leave/nothing/long/ago/time/one/still/forever/never/last/then/once/ever/again/return/returning/returned" as age. Understand "kitchen/attic/moved/up/there/stove/furnace/fire/warmth/warm/cold/only/back/evening/dormer/dormers/throughout" as the house. Understand "night/dark/dim/around/darkness/dusk/everything/circle/shadow/shadows/beyond/see/seen/unseen" as light. Understand "school/schoolroom/classroom/all/outside/out/shrunk/going/go/morning/street/out/half/pack/going/full/birds/chirping/hedge/bright/staring/stare/window/such/life/days/day" as the world. Understand "scratching/scratch/hunched/hunch/away/words/spidered/spider/stories/story/trace/traced/write/written/writes/writings/hear/heard/unheard/record/recorded" as writing. Understand "voices/hiding/under/hearing/voice/forgotten/forget/gone/once/pictures/perhaps/always/things/thing/could/have/been/whisper/whispers/whispering/ghosts/ghost/gather/gathered/mother/soft/least/eyes/eye/glimpses/glimpse" as memory. Section - Parsing Keywording is an action applying to one visible thing. Understand "[any theme]" as keywording. Carry out keywording: try finding meaning in the noun. [We could actually just use the "finding meaning in" rules for keywording; this could be made into a more flexible framework in case we were doing things other than keywording, such as interacting with objects that suggested themes rather than interacting directly with the themes themselves.] Added-text-keywording is an action applying to one visible thing and one topic. Understand "[any theme] [text]" as added-text-keywording. [If the player enters more than one word, this captures the first word and keywords it -- assuming that the first word is a theme.] Instead of added-text-keywording: try keywording the noun; rule succeeds. [If something is entered that isn't one of our themes -- a word like "in," or a typo, or a standard IF command -- we just reroute it to a random keyword.] Random-keywording is an action applying to nothing. Empty-keywording is an action applying to one topic. Understand "[text]" as empty-keywording. [This catches what might be parser errors.] Carry out empty-keywording: try keywording a random theme. Carry out random-keywording: try keywording a random theme. Instead of doing anything other than keywording or random-keywording or empty-keywording or transitioning or finding meaning in or helping or crediting or abouting or summing up: Try random-keywording. [Much of this may not be necessary, because of Juhana Leitonen's code for replacing the standard parser, but it's good to have it there. Since "summing up" is done by an instead rule, we probably don't need that in there either.] Rule for printing a parser error: Try random-keywording; abide by the advance time rule. [This increments the turn count, so if the game starts with a parser error the turn can be undone.] After printing a parser error: Say "[run paragraph on]". [This prevents an extra blank line from printing after the parser error routine triggers a random keyword. Thanks to EmacsUser for this.] Before asking which do you mean: try random-keywording instead. Rule for supplying a missing noun: Try random-keywording instead. [I'm not sure that these lines actually do anything.] Understand the command "light" as something new. [so it doesn't interfere with the keyword] Understand the command "go" as something new. Instead of going outside: try keywording the world. [Since "out" and "outside" are supposed to be synonyms for the world, and our parser modficiations don't override that.] Instead of going up: try keywording the house. [Ditto for "up." ] [See also the sections at the end by Juhana Leitonen and Victor Gijsbers, which respectively rip out most of the parser and redirect disambiguation requests to random keywords -- so the input "the" doesn't result in a disambiguation request.] Section - Moving from Theme to Theme The dominant metaphor is a theme that varies. The dominant metaphor is usually the table. [The dominant metaphor is whatever theme we're currently on.] The target idea is a theme that varies. The target idea is usually the table. [This is a global variable that keeps track of what theme we're trying to reach on a given turn.] The step-count is a number that varies. The step-count is usually 0. [The step-count is used to keep track of how many quips we have printed so far in a turn, so we can cut it off before five or so, and we don't get caught in an infinite loop.] Transitioning is an action applying to one visible thing. Carry out transitioning: if there is a used of false in the transition-table of the noun: [if we haven't gone through the whole transition-table, choose the next row and mark it as used] choose a row with a used of false in the transition-table of the noun; say the quip entry; now the used entry is true; if the step-count is less than 3: [If we haven't said that much, wander randomly] now the dominant metaphor is a random member of the connections entry; otherwise if the step-count is less than 5: [if we've already said a few things, try to get to the target if we can] if the target idea is listed in the connections entry: now the dominant metaphor is the target idea; otherwise: now the dominant metaphor is a random member of the connections entry; otherwise: [if we've already said a bunch of things and we haven't hit the target entry yet, panic and jump to the target entry] say "[line break]"; now the dominant metaphor is the target idea; otherwise if there is a repeatable of true in the transition-table of the noun: [we should hit this if we've already said every other quip; there should always be a repeatable of true, since the tables are designed so that's the last line] choose a row with a repeatable of true in the transition-table of the noun; say the quip entry; now the used entry is true; increase the end-count of the noun by 1; [we've just printed the last quip for this theme, so increase the end-count] if the step-count is less than 3: [If we haven't said that much, wander randomly] now the dominant metaphor is a random member of the connections entry; otherwise if the step-count is less than 5: [if we've already said a few things, try to get to the target if we can] if the target idea is listed in the connections entry: now the dominant metaphor is the target idea; otherwise: now the dominant metaphor is a random member of the connections entry; otherwise: [if we've already said a bunch of things and we haven't hit the target entry yet, panic and jump to the target entry] say "[line break]"; now the dominant metaphor is the target idea. Finding meaning in is an action applying to one visible thing. Carry out finding meaning in something (called the token): if the token is not a theme: [this probably should never get called] try random-keywording; otherwise: now the target idea is the token; [set the target to the player's command] now the step-count is 0; if the dominant metaphor is the target idea: [we're already there!] try transitioning the target idea; say "[line break]"; otherwise: while the dominant metaphor is not the target idea: [wander till you hit the target idea, or until the step-count reaches 5 and the code for transitioning forces us to the target idea] try transitioning the dominant metaphor; increase the step-count by 1; [and we still haven't printed anything about the target idea, so:] try transitioning the target idea; if the step-count is less than 5: [for some reason, if the step-count hits 5, it's going to print a line break anyway] say "[line break]". Section - Ending [When a theme is finished -- it's hit its end-cap -- we print an ending tailored to that theme.] After finding meaning in: [This is an after rule rather than an every turn rule just to make sure that we go straight to the ending once we've hit the end-cap] if a theme is finished: try summing up a random finished theme; end the story finally. [We may need this in order to ensure that the game actually ends, if we got here via a parser error. I think this breaks final "undo" though.] Summing up is an action applying to one visible thing. [Using different "instead" rules to print an ending for each theme.] Carry out summing up: [Catches any bug where we somehow sum up something that isn't a theme, or a theme with an ending that isn't defined.] end the story finally. Carry out summing up the table: wait for any key; say "every night in the attic scratching away at the old wooden table"; wait for any key. Carry out summing up the notebook: wait for any key; say "the pages faded the words faded scratching out"; wait for any key. Carry out summing up age: wait for any key; say "all gone in time and only time left"; wait for any key; rule succeeds. Carry out summing up the house: wait for any key; say "no more house and no one in it only the the attic [paragraph break]"; wait for any key; say "scratching away at the table every night". Carry out summing up light: wait for any key; say "all faded but the dark wood table". Carry out summing up the world: wait for any key; say "the world gone on perhaps or still going [paragraph break]"; wait for any key; say "going on and at the table scratching away every night". Carry out summing up writing: wait for any key; say "ever recording the voices telling how [paragraph break]"; wait for any key; say "every night in the attic scratching away at the old wooden table". Carry out summing up memory: wait for any key; say "only the voices left behind the shadows". When play begins: [since "undo" after the end is broken, delist it] choose row with a final response rule of immediately undo rule in the Table of Final Question Options; delete the final question wording entry. Section - Tables of Quips [The first column is what we print, the second tells us whether it gets used up, the third tells us if it has been used up, the fourth tells us which themes we can get to from there] Table 1.1 - Table Transitions Quip Repeatable Used Connections "the table from the old kitchen [rp]" false false {house, table} "moved up from the kitchen so long ago [rp]" false false {house, age} "the table's wood dark in the dim light [rp]" false false {light} "hunched over the table now scratching out the old voices [rp]" false false {writing, memory, age} "once hiding under the table hearing the voices in the old kitchen [rp]" false false {house, memory, age} "the notebook flat on the table now the dim light around it [rp]" false false {light, notebook} "old cold wood and the soft cardboard and paper [rp]" false false {notebook} "the table the notebook the scratching nothing else left [rp]" true false {notebook, writing, world} Table 2.1 - Notebook Transitions Quip Repeatable Used Connections "scratching away in the old spiral notebook [rp]" false false {writing, age} "all the old notebooks from school [rp]" false false {age, world} "scratching away in the old spiral notebook [rp]" false false {writing, age} "its cover shaded in old pencil [rp]" false false {writing, age, light} "the cover scribbled over in some schoolroom long forgotten [rp]" false false {writing, memory, world} "the cover scribbled over and the old words fading together [rp]" false false {writing, memory, age, notebook} "time the one scribbled word still there [rp]" false false {writing, age} "inside the pages spidered over [rp]" false false {writing, light} "scratching away at the table in the dim [rp]" true false {light, table, writing} Table 3.1 - Age Transitions Quip Repeatable Used Connections "so long up there [rp]" false false {age, house} "so long all forgotten [rp]" false false {age, memory} "forever at the old table [rp]" false false {table} "all gone in time [rp]" true false {world, memory, writing} Table 4.1 - House Transitions Quip Repeatable Used Connections "up in the old attic [rp]" false false {age, table} "so long all forgotten [rp]" false false {age, memory} "forever at the old table [rp]" false false {table, age} "once in the kitchen by the stove [rp]" false false {table, age, memory} "by the stove or the furnace or the fire once [rp]" false false {age, memory, world} "someone's childhood in the warmth by a fire [rp]" false false {memory, world} "warmth or cold or light or darkness all pictures all stories gone now [rp]" false false {memory, writing, age, light} "never outside the attic for so long now [rp]" false false {table, age} "all shrunk to the attic where now [rp]" true false {table, age, world} Table 5.1 - Light Transitions Quip Repeatable Used Connections "night or dusk perhaps [rp]" false false {age, memory} "everything dim the table a more solid darkness [rp]" false false {table} "only a circle of light on the table [rp]" false false {table, house} "nothing but shadow outside [rp]" false false {world, house} "the gray pages traced with fading pencil [rp]" false false {notebook, writing} "all faded at last [rp]" true false {world, house, notebook, age, memory} Table 6.1 - World Transitions Quip Repeatable Used Connections "the outside still going on perhaps [rp]" false false {memory, age} "once out on the street in the morning [rp]" false false {house, memory, light} "on the street in the half light [rp]" false false {house, light} "going to school pack full the birds chirping in the hedge [rp]" false false {age, memory} "the old notebook in the pack then [rp]" false false {notebook, age, memory} "in the schoolroom staring out the bright window [rp]" false false {writing, light} "back to the house always dark in the evening [rp]" false false {house, light, age} "once out in the world now at the table [rp]" true false {table, writing, age} Table 7.1 - Writing Transitions Quip Repeatable Used Connections "always writing in the old notebook [rp]" false false {age, notebook} "writing all the forgotten things [rp]" false false {memory} "such a world could have been written [rp]" false false {world, memory} "such a world if it were there outside [rp]" false false {world, house} "whispers of the outside in the pages sometimes [rp]" false false {world, house, age} "what a world could have been if the shadows had once lifted [rp]" false false {world, light, age, memory} "writing now only the notebook in the circle of light on the table [rp]" false false {notebook, light, table} "the notebook in the circle of dim on the table [rp]" false false {notebook, light, table} "the old voices whispering in the dormers all heard and recorded [rp]" false false {house, memory, age} "at the table scratching in the notebook ever now and again [rp]" true false {table, notebook, age} Table 8.1 - Memory Transitions Quip Repeatable Used Connections "whispering just beyond the light [rp]" false false {age, light} "the old ghosts gathered round the table unseen unheard [rp]" false false {age, table, light} "mother perhaps at the kitchen table a soft voice a voice at least [rp]" false false {table, writing, house} "the old ghosts throughout the house [rp]" false false {house, age} "the eyes unseen the voices still on the page [rp]" false false {light, writing, notebook} "glimpses of the old life at least the old days [rp]" false false {world, age} "when once outside when once at the table back at the table now [rp]" false false {world, table, age} "the shadows all returning or never left [rp]" true false {world, light, table} Table 16.1 - Miscellaneous Transitions Quip Repeatable Used "This is a miscellaneous transition. [rp]" true false Section Grammar (in place of Section SR4/10 - Grammar in Standard Rules by Graham Nelson) [by Juhana Leitonen] Understand "quit" or "q" as quitting the game. Understand "save" as saving the game. Understand "restart" as restarting the game. Understand "restore" as restoring the game. Understand "verify" as verifying the story file. Understand "version" as requesting the story file version. Understand "script" or "script on" or "transcript" or "transcript on" as switching the story transcript on. Understand "script off" or "transcript off" as switching the story transcript off. Section - Disable disambiguation questions [by Victor Gijsbers, except for the last two lines] ambiguity_alert is a number that varies. ambiguity_alert is usually 0. [Here we rewrite NounDomain to stop disambiguation questions.] Include (- [ NounDomain domain1 domain2 context first_word i j k l answer_words marker; #Ifdef DEBUG; if (parser_trace >= 4) { print " [NounDomain called at word ", wn, "^"; print " "; if (indef_mode) { print "seeking indefinite object: "; if (indef_type & OTHER_BIT) print "other "; if (indef_type & MY_BIT) print "my "; if (indef_type & THAT_BIT) print "that "; if (indef_type & PLURAL_BIT) print "plural "; if (indef_type & LIT_BIT) print "lit "; if (indef_type & UNLIT_BIT) print "unlit "; if (indef_owner ~= 0) print "owner:", (name) indef_owner; new_line; print " number wanted: "; if (indef_wanted == INDEF_ALL_WANTED) print "all"; else print indef_wanted; new_line; print " most likely GNAs of names: ", indef_cases, "^"; } else print "seeking definite object^"; } #Endif; ! DEBUG match_length = 0; number_matched = 0; match_from = wn; SearchScope(domain1, domain2, context); #Ifdef DEBUG; if (parser_trace >= 4) print " [ND made ", number_matched, " matches]^"; #Endif; ! DEBUG wn = match_from+match_length; ! If nothing worked at all, leave with the word marker skipped past the ! first unmatched word... if (number_matched == 0) { wn++; rfalse; } ! Suppose that there really were some words being parsed (i.e., we did ! not just infer). If so, and if there was only one match, it must be ! right and we return it... if (match_from <= num_words) { if (number_matched == 1) { i=match_list-->0; return i; } ! ...now suppose that there was more typing to come, i.e. suppose that ! the user entered something beyond this noun. If nothing ought to follow, ! then there must be a mistake, (unless what does follow is just a full ! stop, and or comma) if (wn <= num_words) { i = NextWord(); wn--; if (i ~= AND1__WD or AND2__WD or AND3__WD or comma_word or THEN1__WD or THEN2__WD or THEN3__WD or BUT1__WD or BUT2__WD or BUT3__WD) { if (lookahead == ENDIT_TOKEN) rfalse; } } } ! Now look for a good choice, if there's more than one choice... number_of_classes = 0; if (number_matched == 1) i = match_list-->0; if (number_matched > 1) { i = Adjudicate(context); if (i == -1) rfalse; if (i == 1) rtrue; ! Adjudicate has made a multiple ! object, and we pass it on } ! If i is non-zero here, one of two things is happening: either ! (a) an inference has been successfully made that object i is ! the intended one from the user's specification, or ! (b) the user finished typing some time ago, but we've decided ! on i because it's the only possible choice. ! In either case we have to keep the pattern up to date, ! note that an inference has been made and return. ! (Except, we don't note which of a pile of identical objects.) if (i ~= 0) { if (dont_infer) return i; if (inferfrom == 0) inferfrom=pcount; pattern-->pcount = i; return i; } ! If we get here, there was no obvious choice of object to make. (+ ambiguity_alert +) = 1; rfalse; ]; ! end of NounDomain -) instead of "Noun Domain" in "Parser.i6t". Rule for printing a parser error when ambiguity_alert is 1: now ambiguity_alert is 0; abide by the advance time rule; try random-keywording instead.