﻿<!--Saved by Quest 5.9.9166.36226-->
<asl version="580">
  <implied element="object" property="alt" type="simplestringlist" />
  <implied element="command" property="pattern" type="simplepattern" />
  <implied element="command" property="script" type="script" />
  <implied element="command" property="multiple" type="AssociatedScope" />
  <implied element="object" property="displayverbs" type="simplestringlist" />
  <implied element="object" property="inventoryverbs" type="simplestringlist" />
  <implied element="walkthrough" property="steps" type="simplestringlist" />
  <implied element="timer" property="interval" type="int" />
  <implied element="timer" property="script" type="script" />
  <implied element="turnscript" property="script" type="script" />
  <template name="UnresolvedObject"></template>
  <template name="UnrecognisedCommand"></template>
  <template name="EditorVerbDefaultExpression"></template>
  <template name="LanguageId">en</template>
  <template name="WantRestartGame">Are you sure you want to restart the game?</template>
  <template name="Again1">again</template>
  <template name="Again2">g</template>
  <template name="NothingToRepeat">There is nothing to repeat.</template>
  <template name="UnresolvedLocation">{=WriteVerb(game.pov, "can't")} go there.</template>
  <template name="DefaultObjectDescription">Nothing out of the ordinary.</template>
  <template name="DefaultSelfDescription">Looking good.</template>
  <template name="SeeListHeader">{=WriteVerb(game.pov, "can")} see</template>
  <template name="GoListHeader">{=WriteVerb(game.pov, "can")} go</template>
  <template name="And">and</template>
  <template name="Nothing">nothing</template>
  <template name="Or">or</template>
  <template name="NothingToUndo">Nothing to undo!</template>
  <template name="NotCarryingAnything">{=WriteVerb(game.pov, "be")} not carrying anything.</template>
  <template name="CarryingListHeader">{=WriteVerb(game.pov, "be")} carrying</template>
  <template name="YouAreIn">{=WriteVerb(game.pov, "be")} in</template>
  <template name="LookAt">Look at</template>
  <template name="Take">Take</template>
  <template name="SpeakTo">Speak to</template>
  <template name="Use">Use</template>
  <template name="Drop">Drop</template>
  <template name="GoTo">Go to</template>
  <template name="Go">Go</template>
  <template name="SwitchOn">Switch on</template>
  <template name="SwitchOff">Switch off</template>
  <template name="Open">Open</template>
  <template name="Close">Close</template>
  <template name="Eat">Eat</template>
  <template name="NeutralGender">it</template>
  <template name="MaleGender">he</template>
  <template name="FemaleGender">she</template>
  <template name="SelfGender">you</template>
  <template name="NeutralPluralGender">they</template>
  <template name="MalePluralGender">they</template>
  <template name="FemalePluralGender">they</template>
  <template name="NeutralArticle">it</template>
  <template name="MaleArticle">him</template>
  <template name="FemaleArticle">her</template>
  <template name="SelfArticle">yourself</template>
  <template name="NeutralPluralArticle">them</template>
  <template name="MalePluralArticle">them</template>
  <template name="FemalePluralArticle">them</template>
  <template name="NeutralPossessive">its</template>
  <template name="MalePossessive">his</template>
  <template name="FemalePossessive">her</template>
  <template name="SelfPossessive">your</template>
  <template name="NeutralPluralPossessive">their</template>
  <template name="MalePluralPossessive">their</template>
  <template name="FemalePluralPossessive">their</template>
  <template name="SelfAlias">me</template>
  <template name="SelfAlt">me; myself; self</template>
  <template name="AllObjects">all; everything</template>
  <template name="ParserIgnorePrefixes">the; a; an</template>
  <template name="UseDefaultPrefixIfNamed">false</template>
  <template name="Score">Score</template>
  <template name="Health">Health</template>
  <template name="Money">Money</template>
  <template name="CannotDoThat">{=WriteVerb(game.pov, "can't")} do that.</template>
  <template name="Done">Done.</template>
  <template name="ContainerContentsPrefix">containing</template>
  <template name="SurfaceContentsPrefix">on which there is</template>
  <template name="LockedExit">That way is locked.</template>
  <template name="NoKey">{=WriteVerb(game.pov, "do")} not have the key.</template>
  <template name="UnlockMessage">Unlocked.</template>
  <template name="LockMessage">Locked.</template>
  <template name="DefaultOops">There is nothing to correct.</template>
  <template name="VerbObjectSeparator">with; using</template>
  <template name="DefaultMultiObjectVerb">That doesn't work.</template>
  <template name="MultiObjectVerbMenu">With which object?</template>
  <template name="UseOnMenu">On which object?</template>
  <template name="GiveToMenu">To which object?</template>
  <template name="NoObjectsAvailable">There are no objects available to do that with.</template>
  <template name="Yes">Yes</template>
  <template name="No">No</template>
  <template name="By">by</template>
  <template name="NothingToTake">Nothing here to take.</template>
  <template name="NothingToDrop">{=WriteVerb (game.pov, "'ve")} nothing to drop.</template>
  <template name="NothingToWear">{=WriteVerb (game.pov, "'ve")} nothing to wear.</template>
  <template name="NothingToRemove">{=WriteVerb (game.pov, "'ve")} nothing to take off.</template>
  <template name="NeutralWornModifier">worn</template>
  <template name="MaleWornModifier">worn</template>
  <template name="FemaleWornModifier">worn</template>
  <template name="NeutralPluralWornModifier">worn</template>
  <template name="MalePluralWornModifier">worn</template>
  <template name="FemalePluralWornModifier">worn</template>
  <template name="Wear">Wear</template>
  <template name="wear">put #object# on; wear; put on; don; wear</template>
  <template name="Remove">Remove</template>
  <template name="remove">take #object# off; remove; take off; doff</template>
  <template name="CompassNW">northwest</template>
  <template name="CompassN">north</template>
  <template name="CompassNE">northeast</template>
  <template name="CompassW">west</template>
  <template name="CompassE">east</template>
  <template name="CompassSW">southwest</template>
  <template name="CompassS">south</template>
  <template name="CompassSE">southeast</template>
  <template name="CompassUp">up</template>
  <template name="CompassDown">down</template>
  <template name="CompassIn">in</template>
  <template name="CompassOut">out</template>
  <template name="CompassDirectionPrefix"></template>
  <template name="CompassDirectionSuffix"></template>
  <template name="UpDownDirectionPrefix"></template>
  <template name="UpDownDirectionSuffix"></template>
  <template name="InOutDirectionPrefix"></template>
  <template name="InOutDirectionSuffix"></template>
  <template name="CompassNWShort">nw</template>
  <template name="CompassNShort">n</template>
  <template name="CompassNEShort">ne</template>
  <template name="CompassWShort">w</template>
  <template name="CompassEShort">e</template>
  <template name="CompassSWShort">sw</template>
  <template name="CompassSShort">s</template>
  <template name="CompassSEShort">se</template>
  <template name="CompassUpShort">u</template>
  <template name="CompassDownShort">d</template>
  <template name="CompassInShort"></template>
  <template name="CompassOutShort">o</template>
  <template name="InventoryLabel">Inventory</template>
  <template name="StatusLabel">Status</template>
  <template name="PlacesObjectsLabel">Places and Objects</template>
  <template name="CompassLabel">Compass</template>
  <template name="InButtonLabel">in</template>
  <template name="OutButtonLabel">out</template>
  <template name="EmptyListLabel">(empty)</template>
  <template name="NothingSelectedLabel">(nothing selected)</template>
  <template name="TypeHereLabel">Type here...</template>
  <template name="ContinueLabel">Continue...</template>
  <template name="go"><![CDATA[^go to (?<exit>.*)$|^go (?<exit>.*)$|^(?<exit>north|east|south|west|northeast|northwest|southeast|southwest|in|out|up|down|n|e|s|w|ne|nw|se|sw|o|u|d)$]]></template>
  <template name="lookdir"><![CDATA[^look (?<exit>north|east|south|west|northeast|northwest|southeast|southwest|out|up|down|n|e|s|w|ne|nw|se|sw|o|u|d)$]]></template>
  <template name="look">^look$|^l$</template>
  <template name="lookat">look at; look; x; examine; exam; ex</template>
  <template name="take">take; get; pick up</template>
  <template name="undo">^undo$</template>
  <template name="inventory">^i$|^inv$|^inventory$</template>
  <template name="quit">^quit$</template>
  <template name="drop">drop</template>
  <template name="use">use</template>
  <template name="speakto">speak to; speak; talk to; talk</template>
  <template name="open">open</template>
  <template name="close">close</template>
  <template name="put"><![CDATA[^(put|insert|place|drop) (?<object1>.*) (on to|onto|in to|into|on|in) (?<object2>.*)$]]></template>
  <template name="removefrom"><![CDATA[^(remove|take|get|eject) (?<object1>.*) (from|out of|off|out) (?<object2>.*)$]]></template>
  <template name="ask"><![CDATA[^ask (?<object>.*) about (?<text>.*)$]]></template>
  <template name="tell"><![CDATA[^tell (?<object>.*) about (?<text>.*)$]]></template>
  <template name="tellto"><![CDATA[^(tell|ask) (?<object>.*) to (?<text>.*)$]]></template>
  <template name="alttellto"><![CDATA[^(?<object>.*), (?<text>.*)$]]></template>
  <template name="oops"><![CDATA[^oops (?<text>.*)$]]></template>
  <template name="buy">buy; purchase</template>
  <template name="climb">climb</template>
  <template name="drink">drink</template>
  <template name="eat">eat</template>
  <template name="givesingle">give</template>
  <template name="give"><![CDATA[^give (?<object1>.*) to (?<object2>.*)$]]></template>
  <template name="hit">hit</template>
  <template name="kill">kill</template>
  <template name="kiss">kiss</template>
  <template name="knock">knock</template>
  <template name="lick">lick</template>
  <template name="lie">lie on; lie upon; lie down on; lie down upon</template>
  <template name="listento">listen to</template>
  <template name="lock">lock</template>
  <template name="move">move</template>
  <template name="pull">pull</template>
  <template name="push">push</template>
  <template name="read">read</template>
  <template name="search">search</template>
  <template name="show">show</template>
  <template name="sit">sit on; sit upon; sit down on; sit down upon</template>
  <template name="smell">smell; sniff</template>
  <template name="taste">taste</template>
  <template name="throw">throw</template>
  <template name="tie">tie</template>
  <template name="touch">touch</template>
  <template name="turnon">turn on; turn #object# on; switch on; switch #object# on</template>
  <template name="turnoff">turn off; turn #object# off; switch off; switch #object# off</template>
  <template name="turn">turn</template>
  <template name="unlock">unlock</template>
  <template name="untie">untie</template>
  <template name="useon"><![CDATA[^use (?<object1>.*) (on|with) (?<object2>.*)$]]></template>
  <template name="listen">^listen$</template>
  <template name="DefaultListen">{=WriteVerb(game.pov, "can't")} hear much.</template>
  <template name="jump">^jump$</template>
  <template name="DefaultJump">{=WriteVerb(game.pov, "jump,")} but nothing happens.</template>
  <template name="sitdown">^sit$|^sit down$</template>
  <template name="DefaultSitDown">No time for lounging about now.</template>
  <template name="liedown">^lie$|^lie down$</template>
  <template name="DefaultLieDown">No time for lounging about now.</template>
  <template name="sleep">^sleep$|^rest$</template>
  <template name="DefaultSleep">No time for lounging about now.</template>
  <template name="wait">^wait$|^z$</template>
  <template name="DefaultWait">Time passes.</template>
  <template name="xyzzy">^xyzzy$</template>
  <template name="DefaultXyzzy">Surprisingly, absolutely nothing happens.</template>
  <template name="help">^help$|^\?$</template>
  <template name="save">^save$</template>
  <template name="DefaultHelp"><![CDATA[<u>Quick Help</u><br/><br/>
<b>- Objects:</b>  Try LOOK AT..., SPEAK TO..., TAKE..., DROP..., OPEN..., GIVE... TO..., USE... ON/WITH...<br/>
<b>- Inventory:</b>  See which items you are carrying by typing I, INV or INVENTORY.<br/>
<b>- Moving around:</b>  Press the compass buttons, or type GO NORTH, SOUTH, E, GO TO...<br/>
<b>- Shortcuts:</b>  Press the up arrow and down arrow to scroll through commands you have already typed in. Try X... as a shortcut for LOOK AT...]]></template>
  <template name="LanguageSpecificObjectTypes"></template>
  <template name="transcript_on_cmd">^(transcript|script)( on|)$|^enable (script|transcript)$</template>
  <template name="transcript_off_cmd">^(transcript|script) off$|^disable (script|transcript)$</template>
  <template name="view_transcript_cmd">^(view|display|show) (the |)(script|transcript)$</template>
  <template name="version_cmd">^(version|info|about)$</template>
  <template name="DevModeErrorWrongFormat">That's the wrong format.</template>
  <template name="DevModeErrorObjectNotRecognised">The object was not found.</template>
  <template name="DevModeErrorWrongTyp">That's the wrong type.</template>
  <template name="DevModeErrorWrongKey">The key was not found.</template>
  <template name="DevModeExecuteCommand">The command was executed.</template>
  <template name="DevModeNotActive">DevMode is not active!</template>
  <template name="DevModeDescriptionCommands"><![CDATA[<h3>FlyScript - Help</h3><b><u>Object-Commends</u></b><br/>#take object<br/>#drop object<br/>#put object1 in object2<br/>#open object<br/>#close object<br/>#on object<br/>#off object<br/>#to player<br/>#go room<br/><br/><i>Unlike the commands in the game, they are executed directly and without detours via intercept scripts.</i><br/><br/><b><u>Single-Commands</u></b><br/>#clr (clear screen)<br/>#? (help)<br/># (close game)<br/><br/><b><u>Object-Attributes</u></b><br/>#object1.attribute=object2.attribute (attribute assignment of another object)<br/>#object.attribute=true / false (set true / false)<br/>#object.attribute=? / ! (set true / false)<br/>#~object.attribute (toggle true or false)<br/>#object.attribute="value" (string)<br/>#object.attribute=15 (integer)<br/>#object.attribute=25.55 (double)<br/>#object.attribute=[item1,item2,item3] (list)<br/>#object.attribute[]=element (add element to list)<br/>#object.attribute[key]=element (add or overwrite element to list)<br/>#object.attribute=[] (create new list)<br/>#object.attribute={key1:item1,key2:item2,key3:item3} (dictionary)<br/>#object.attribute{key}=element (add or overwrite element to dictionary)<br/>#object.attribute={} (create new dictionary)<br/>#object.attribute (read attribute)<br/>]]></template>
  <template name="DevModeActive"><![CDATA[<b>DevMode: Active</b>]]></template>
  <template name="DevModeInitDegugTable">Debug table initialized.</template>
  <template name="DevModeStartScript">Initialization script started.</template>
  <template name="DevModeSetVerbs">Verbs assigned.</template>
  <template name="DevModeComExecute">Command executed.</template>
  <template name="DevModeComSetAttribute">Set Attribute: </template>
  <template name="DevModeComGetAttribute">Get Attribute: </template>
  <template name="DevModeComSelfTestFailed">The assignment as it should be after the command is incorrect.</template>
  <template name="enter">enter; go in; go into; get in; get into</template>
  <template name="NoTranscriptFeature">This game has no transcript feature.</template>
  <template name="TranscriptAlreadyEnabled">The transcript is already enabled.</template>
  <template name="TranscriptDisabled">End of transcript.</template>
  <template name="TranscriptAlreadyDisabled">The transcript is already disabled.</template>
  <template name="TranscriptEnterFilename">Please enter a transcript name.</template>
  <template name="TranscriptOffAllCaps">TRANSCRIPT OFF</template>
  <template name="Noted">Noted.</template>
  <template name="ShowMenuResponsePrompt"><![CDATA[>> ]]></template>
  <dynamictemplate name="TakeSuccessful">WriteVerb(game.pov, "pick") + " " + object.article + " up."</dynamictemplate>
  <dynamictemplate name="TakeUnsuccessful">WriteVerb(game.pov, "can't") + " take " + object.article + "."</dynamictemplate>
  <dynamictemplate name="FullInventory">WriteVerb(object, "be") + " too heavy to be taken."</dynamictemplate>
  <dynamictemplate name="MaxObjectsInInventory">WriteVerb(game.pov, "can't") + " carry any more items."</dynamictemplate>
  <dynamictemplate name="MaxObjectsInContainer">WriteVerb(game.pov, "can't") + " put more items in " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DropSuccessful">WriteVerb(game.pov, "drop") + " " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DropUnsuccessful">WriteVerb(game.pov, "can't") + " drop " + object.article + "."</dynamictemplate>
  <dynamictemplate name="ObjectCannotBeStored">WriteVerb(game.pov, "can't") + " put " + object.article + " there."</dynamictemplate>
  <dynamictemplate name="AlreadyTaken">WriteVerb(game.pov, "be") + " already carrying " + object.article + "."</dynamictemplate>
  <dynamictemplate name="NotCarrying">WriteVerb(game.pov, "be") + " not carrying " + object.article + "."</dynamictemplate>
  <dynamictemplate name="CantUse">WriteVerb(game.pov, "can't") + " use " + object.article + "."</dynamictemplate>
  <dynamictemplate name="CantGive">WriteVerb(game.pov, "can't") + " give " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultSpeakTo">You don't need to speak.</dynamictemplate>
  <dynamictemplate name="ObjectNotOpen">CapFirst(GetDefiniteName(object)) + " " + Conjugate(object, "be") + " not open."</dynamictemplate>
  <dynamictemplate name="AlreadyOpen">WriteVerb(object, "be") + " already open."</dynamictemplate>
  <dynamictemplate name="AlreadyClosed">WriteVerb(object, "be") + " already closed."</dynamictemplate>
  <dynamictemplate name="CantOpen">WriteVerb(game.pov, "can't") + " open " + object.article + "."</dynamictemplate>
  <dynamictemplate name="CantClose">WriteVerb(game.pov, "can't") + " close " + object.article + "."</dynamictemplate>
  <dynamictemplate name="OpenSuccessful">WriteVerb(game.pov, "open") + " " + object.article + "."</dynamictemplate>
  <dynamictemplate name="CloseSuccessful">WriteVerb(game.pov, "close") + " " + object.article + "."</dynamictemplate>
  <dynamictemplate name="AlreadyThere">WriteVerb(object, "be") + " already there."</dynamictemplate>
  <dynamictemplate name="ObjectContains">WriteVerb(object, "contain")</dynamictemplate>
  <dynamictemplate name="ContainerFull">WriteVerb(object, "be") + " full."</dynamictemplate>
  <dynamictemplate name="DisambiguateMenu">"Please choose which '" + text + "' you mean:"</dynamictemplate>
  <dynamictemplate name="UndoTurn">"Undo: " + text</dynamictemplate>
  <dynamictemplate name="DefaultAsk">You don't need to speak.</dynamictemplate>
  <dynamictemplate name="DefaultTell">You don't need to speak.</dynamictemplate>
  <dynamictemplate name="LockedObject">WriteVerb(object, "be") + " locked."</dynamictemplate>
  <dynamictemplate name="AlreadyLocked">WriteVerb(object, "be") + " already locked."</dynamictemplate>
  <dynamictemplate name="AlreadyUnlocked">WriteVerb(object, "be") + " already unlocked."</dynamictemplate>
  <dynamictemplate name="CannotLockOpen">WriteVerb(game.pov, "cannot") + " lock " + object.article + " when " + object.gender + " " + Conjugate(object, "be") + " open."</dynamictemplate>
  <dynamictemplate name="AlreadySwitchedOn">WriteVerb(object, "be") + " already switched on."</dynamictemplate>
  <dynamictemplate name="AlreadySwitchedOff">WriteVerb(object, "be") + " already switched off."</dynamictemplate>
  <dynamictemplate name="SwitchedOn">WriteVerb(game.pov, "switch") + " " + object.article + " on."</dynamictemplate>
  <dynamictemplate name="SwitchedOff">WriteVerb(game.pov, "switch") + " " + object.article + " off."</dynamictemplate>
  <dynamictemplate name="Eaten">WriteVerb(game.pov, "eat") + " " + object.article + "."</dynamictemplate>
  <dynamictemplate name="ObjectDoesNotContain">CapFirst(GetDisplayAlias(object1)) + " " + Conjugate(object1, "do") + " not contain " + GetDisplayAlias(object2) + "."</dynamictemplate>
  <dynamictemplate name="YouLooking">WriteVerb(game.pov, "be") + " looking " + text +"."</dynamictemplate>
  <dynamictemplate name="LookAtDarkness">"It is too dark to make anything out."</dynamictemplate>
  <dynamictemplate name="WearSuccessful">WriteVerb(game.pov, "put") + " " + object.article + " on."</dynamictemplate>
  <dynamictemplate name="WearUnsuccessful">WriteVerb(game.pov, "can't") + " wear " + object.article + "."</dynamictemplate>
  <dynamictemplate name="CannotWearIfNotHeld">WriteVerb(game.pov, "would") + " need to get " + object.article + " before " + game.pov.gender + " can put " + object.article + " on."</dynamictemplate>
  <dynamictemplate name="CannotRemoveIfNotHeld">WriteVerb(game.pov, "would") + " need to get " + object.article + " before " + game.pov.gender + " can take " + object.article + " off."</dynamictemplate>
  <dynamictemplate name="AlreadyWearing">WriteVerb(game.pov, "be") + " already wearing " + object.article + "."</dynamictemplate>
  <dynamictemplate name="CannotRemoveIfNotWearing">WriteVerb(game.pov, "be") + " not wearing " + object.article + "."</dynamictemplate>
  <dynamictemplate name="NotRemovable">WriteVerb(game.pov, "cannot") + " remove " + object.article + "!"</dynamictemplate>
  <dynamictemplate name="CannotWearOver">WriteVerb(game.pov, "cannot") + " wear that over " + GetDisplayGarment(object) + "."</dynamictemplate>
  <dynamictemplate name="CannotWearWith">WriteVerb(game.pov, "cannot") + " wear that while wearing " + GetDisplayGarment(object) + "."</dynamictemplate>
  <dynamictemplate name="RemoveSuccessful">WriteVerb(game.pov, "take") + " " + object.article + " off."</dynamictemplate>
  <dynamictemplate name="RemoveFirst">WriteVerb(game.pov, "can't") + " remove that while wearing " + GetDisplayGarment(object) + "."</dynamictemplate>
  <dynamictemplate name="DefaultBuy">WriteVerb(game.pov, "can't") + " buy " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultClimb">WriteVerb(game.pov, "can't") + " climb " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultDrink">WriteVerb(game.pov, "can't") + " drink " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultEat">WriteVerb(game.pov, "can't") + " eat " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultGive">WriteVerb(object1, "do") + " not want " + object2.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultHit">WriteVerb(game.pov, "can't") + " hit " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultKill">WriteVerb(game.pov, "can't") + " kill " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultKiss">WriteVerb(game.pov, "can't") + " kiss " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultKnock">WriteVerb(game.pov, "can't") + " knock " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultLick">WriteVerb(game.pov, "can't") + " lick " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultLie">WriteVerb(game.pov, "can't") + " lie on " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultListenTo">WriteVerb(game.pov, "listen,") + " but " + object.gender + " makes no sound."</dynamictemplate>
  <dynamictemplate name="DefaultLock">WriteVerb(game.pov, "can't") + " lock " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultMove">WriteVerb(game.pov, "can't") + " move " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultPull">WriteVerb(game.pov, "can't") + " pull " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultPush">WriteVerb(game.pov, "can't") + " push " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultRead">WriteVerb(game.pov, "can't") + " read " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultSearch">You stand there, confused about how to start, until you decide not to.</dynamictemplate>
  <dynamictemplate name="DefaultShow">WriteVerb(game.pov, "can't") + " show " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultSit">WriteVerb(game.pov, "can't") + " sit on " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultSmell">All you smell is trash.</dynamictemplate>
  <dynamictemplate name="DefaultTaste">WriteVerb(game.pov, "can't") + " taste " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultThrow">WriteVerb(game.pov, "can't") + " throw " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultTie">WriteVerb(game.pov, "can't") + " tie " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultTouch">WriteVerb(game.pov, "can't") + " touch " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultTurnOn">WriteVerb(game.pov, "can't") + " turn " + object.article + " on."</dynamictemplate>
  <dynamictemplate name="DefaultTurnOff">WriteVerb(game.pov, "can't") + " turn " + object.article + " off."</dynamictemplate>
  <dynamictemplate name="DefaultTurn">WriteVerb(game.pov, "can't") + " turn " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultUnlock">WriteVerb(game.pov, "can't") + " unlock " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultUntie">WriteVerb(game.pov, "can't") + " untie " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultUseOn">WriteVerb(game.pov, "can't") + " use " + object2.article + " that way."</dynamictemplate>
  <dynamictemplate name="DefaultWear">WriteVerb(game.pov, "can't") + " wear " + object.article + "."</dynamictemplate>
  <dynamictemplate name="DefaultTellTo">You don't need to speak.</dynamictemplate>
  <dynamictemplate name="DevModeErrorCantFindObject">"The object with the name '" + text + "' cannot be found."</dynamictemplate>
  <dynamictemplate name="DevModeErrorCantFindAttribute">"The attribute with the name '" + text + "' cannot be found."</dynamictemplate>
  <dynamictemplate name="DefaultEnter">WriteVerb(game.pov, "can't") + " enter " + object.article + "."</dynamictemplate>
  <dynamictemplate name="ToDisableTranscript"><![CDATA["<b><i>[  Enter </i>" + Template("TranscriptOffAllCaps") + "<i> to disable the transcript.  ]</i></b>"]]></dynamictemplate>
  <dynamictemplate name="TranscriptEnabledMessage"><![CDATA["<hr/>Start of a transcript of:<br/><b>TITLE: </b>" + game.gamename + "<br/><b>AUTHOR: </b>" + game.author + "<br/><b>VERSION: </b>" + game.version + "<br/><b>IFID: </b>" + game.gameid]]></dynamictemplate>
  <delegate name="AddScript" parameters="object" type="" />
  <delegate name="AssociatedScope" parameters="" type="objectlist" />
  <game name="Onion Hugs: &quot;Getting Started&quot;">
    <inherit name="theme_retro" />
    <gameid>c69f7f48-ca3d-495c-9592-25bff07f77a9</gameid>
    <version>0.9</version>
    <firstpublished>2026</firstpublished>
    <feature_advancedscripts />
    <attr name="boundary_lock" type="boolean">false</attr>
    <writelogtofile type="boolean">false</writelogtofile>
    <showpanes type="boolean">false</showpanes>
    <autodescription type="boolean">false</autodescription>
    <showdescriptiononenter type="boolean">false</showdescriptiononenter>
    <echocommand type="boolean">false</echocommand>
    <showlocation type="boolean">false</showlocation>
    <feature_pictureframe />
    <clearframe />
    <nowhere_intro type="stringlist" />
    <showtitle type="boolean">false</showtitle>
    <category>Fantasy</category>
    <typing_test type="stringlist" />
    <attr name="ott_test" type="boolean">false</attr>
    <description><![CDATA[[Content warning: Unease, emotions, potentially uncomfortable sensory descriptions. Eyes?]<br/>[Keyboard required]<br/>[Contains background music and sounds]<br/>[Play time: 30+ minutes]<br/>. . . .<br/><br/>Grotto Vale is the safest place in the entire Calliope. It's also dark, full of trash, and easy to get lost in. <br/><br/>Get in the snailsweeper, and blaze a slime trail from nowhere back to somewhere.<br/><br/>In this introduction, get settled in your snailsweeper before your journey gets underway.<br/><br/>. . . .<br/><br/>You will be thanked at the end. You could be thanked six times, depending on what you do. <br/><br/>What you do matters. If you're curious enough about enough things, that matters. <br/><br/>. . . .<br/><br/>I've never made a game before.  I've never made anything at all. I don't really remember deciding to do this.<br/><br/>Nobody has play tested this.<br/><br/>Be careful. Be gentle.<br/><br/>. . . .<br/><br/>a solo project by Alex Birch<br/><br/>made in Quest 5.9<br/><br/><br/><br/>]]></description>
    <attr name="move_counter" type="int">0</attr>
    <attr name="next_room" type="string"></attr>
    <subtitle type="string"></subtitle>
    <naphead_text type="stringlist" />
    <attr name="naphead_end" type="int">0</attr>
    <attr name="naphead_invite" type="boolean">false</attr>
    <attr name="naphead_poem" type="boolean">false</attr>
    <pages>0</pages>
    <playerconnect>50</playerconnect>
    <attr name="pc_courage">75</attr>
    <shellventory>1</shellventory>
    <attr name="shlvl_three" type="boolean">false</attr>
    <attr name="shlvl_one" type="boolean">false</attr>
    <attr name="shlvl_two" type="boolean">false</attr>
    <attr name="itswarmdownhere_visited" type="boolean">false</attr>
    <attr name="snailsweeper_visited" type="boolean">false</attr>
    <admintoolsstart type="boolean">false</admintoolsstart>
    <admintools type="boolean">false</admintools>
    <admintoolsstart2 type="boolean">false</admintoolsstart2>
    <getoutlock />
    <attr name="intro_end" type="boolean">false</attr>
    <author>Alex Birch</author>
    <showborder type="boolean">false</showborder>
    <setcustomwidth />
    <customwidth type="int">1000</customwidth>
    <setcustompadding />
    <classiclocation type="boolean">false</classiclocation>
    <bordercolour>White</bordercolour>
    <menufontsize type="int">12</menufontsize>
    <marginscolour>SlateGrey</marginscolour>
    <attr name="intro_ending" type="boolean">false</attr>
    <introendconsole type="boolean">false</introendconsole>
    <introendcredits type="int">0</introendcredits>
    <cover>onionhugs_coverart01.png</cover>
    <enablehyperlinks type="boolean">false</enablehyperlinks>
    <consoleintroed type="boolean">false</consoleintroed>
    <helpstate type="int">0</helpstate>
    <inendconsoletrigger type="boolean">false</inendconsoletrigger>
    <introcomplete type="boolean">false</introcomplete>
    <attr name="curiosity_event">//20+</attr>
    <attr name="care_event">//5</attr>
    <attr name="connection_event">//6</attr>
    <attr name="fear_event" type="int">0</attr>
    <attr name="lonely_event" type="int">0</attr>
    <backgroundimage>calliopemarginnormal3.png</backgroundimage>
    <setbackgroundopacity type="boolean">false</setbackgroundopacity>
    <custompaddingbottom type="int">30</custompaddingbottom>
    <colourblend type="boolean">false</colourblend>
    <attr name="changeroom_newline" type="boolean">false</attr>
    <autodisplayverbs type="boolean">false</autodisplayverbs>
    <level>0</level>
    <shellup1 type="int">1</shellup1>
    <shellup2 type="int">1</shellup2>
    <shellup3 type="int">1</shellup3>
    <shellup4 type="int">1</shellup4>
    <attr name="player_impact" type="int">0</attr>
    <attr name="fear_impact" type="int">0</attr>
    <attr name="lonely_impact" type="int">0</attr>
    <inituserinterface type="script">
    </inituserinterface>
    <roomenter type="script">
      if (game.boundary_lock) {
        JS.uiHide ("#txtCommandDiv")
      }
      else {
        msg (" ")
      }
    </roomenter>
    <scopebackdrop type="script">
      foreach (obj, GetDirectChildren(Global)) {
        list add (items, obj)
      }
    </scopebackdrop>
    <start type="script"><![CDATA[
      JS.eval ("$('body').css('line-height', '1.6');")
      SetFontName ("Lucida Console")
      game.handshake = "https://www.dropbox.com/scl/fi/gpjsrphzigb1417b45cfd/calliopehandshake07272026.mp3?rlkey=c2ojua78po68igj57d1guuymb&st=jvmu7nzs&raw=1"
      game.preload_handshake = "window.cachedAudio0 = new Audio(); "
      game.preload_handshake = game.preload_handshake + "window.cachedAudio0.src = '" + game.handshake + "'; "
      game.preload_handshake = game.preload_handshake + "window.cachedAudio0.preload = 'auto'; "
      game.preload_handshake = game.preload_handshake + "window.cachedAudio0.load();"
      JS.eval (game.preload_handshake)
      game.valebg = "https://www.dropbox.com/scl/fi/3i8fxj3v11h9phrdeby1p/grottovalegothic_.mp3?rlkey=gpik6en39t6hod1sjd9ant46b&st=48wovfwz&raw=1"
      game.preload_valebg = "window.cachedAudio1 = new Audio(); "
      game.preload_valebg = game.preload_valebg + "window.cachedAudio1.src = '" + game.valebg + "'; "
      game.preload_valebg = game.preload_valebg + "window.cachedAudio1.preload = 'auto'; "
      game.preload_valebg = game.preload_valebg + "window.cachedAudio1.load();"
      game.preload_valebg = game.preload_valebg + "window.cachedAudio1.loop = true; "
      JS.eval (game.preload_valebg)
      game.shell_slow = "https://www.dropbox.com/scl/fi/4l1gk8v9wc16f1ancwz67/intheworldyourefrom75_.mp3?rlkey=d5s501z7b1579me5gn4gurg8m&st=vcs392ve&raw=1"
      game.preload_shellslow = "window.cachedAudio2 = new Audio(); "
      game.preload_shellslow = game.preload_shellslow + "window.cachedAudio2.src = '" + game.shell_slow + "'; "
      game.preload_shellslow = game.preload_shellslow + "window.cachedAudio2.preload = 'auto'; "
      game.preload_shellslow = game.preload_shellslow + "window.cachedAudio2.load();"
      JS.eval (game.preload_shellslow)
      game.shell_fast = "https://www.dropbox.com/scl/fi/p92ckf40qil4o02wf1t3w/intheworldyourefrom130.mp3?rlkey=6ljrvgztm5oagr81gd2rdekl5&st=4roqewjv&raw=1"
      game.preload_shellfast = "window.cachedAudio3 = new Audio(); "
      game.preload_shellfast = game.preload_shellfast + "window.cachedAudio3.src = '" + game.shell_fast + "'; "
      game.preload_shellfast = game.preload_shellfast + "window.cachedAudio3.preload = 'auto'; "
      game.preload_shellfast = game.preload_shellfast + "window.cachedAudio3.load();"
      JS.eval (game.preload_shellfast)
      game.journal_bg = "https://www.dropbox.com/scl/fi/qw1yxc9pooae81pn9c56z/fearandyearning75.mp3?rlkey=e2524cbw77rw5qfvoqbud6f6b&st=ktc8qs5f&raw=1"
      game.preload_journal = "window.cachedAudio4 = new Audio(); "
      game.preload_journal = game.preload_journal + "window.cachedAudio4.src = '" + game.journal_bg + "'; "
      game.preload_journal = game.preload_journal + "window.cachedAudio4.preload = 'auto'; "
      game.preload_journal = game.preload_journal + "window.cachedAudio4.load();"
      JS.eval (game.preload_journal)
      game.startmusic = "https://www.dropbox.com/scl/fi/m5w78xt9rew8j2cqvy7ma/butwhileyourehere_welcome.mp3?rlkey=h59lo7e40lw4tt3jqauuxsrc1&st=x0mbns8l&raw=1"
      game.preload_start = "window.cachedAudio5 = new Audio(); "
      game.preload_start = game.preload_start + "window.cachedAudio5.src = '" + game.startmusic + "'; "
      game.preload_start = game.preload_start + "window.cachedAudio5.preload = 'auto'; "
      game.preload_start = game.preload_start + "window.cachedAudio5.load();"
      JS.eval (game.preload_start)
      game.napheadentrance = "https://www.dropbox.com/scl/fi/0vpq0u7cfddn26p2qibcr/curtainsupsfx.mp3?rlkey=wt7bvus1xdz7c6yx9crng5ynr&st=jtu9aixu&raw=1"
      game.preload_naphead = "window.cachedAudio6 = new Audio(); "
      game.preload_naphead = game.preload_naphead + "window.cachedAudio6.src = '" + game.napheadentrance + "'; "
      game.preload_naphead = game.preload_naphead + "window.cachedAudio6.preload = 'auto'; "
      game.preload_naphead = game.preload_naphead + "window.cachedAudio6.load();"
      JS.eval (game.preload_naphead)
      game.treeleaves = "https://www.dropbox.com/scl/fi/ayusz8w8fkhalg8nr1sdo/treeleavesonshell4.mp3?rlkey=kty5zd828nl4zqey8ev8rqpe6&st=3x11q0ly&raw=1"
      game.preload_leaves = "window.cachedAudio7 = new Audio(); "
      game.preload_leaves = game.preload_leaves + "window.cachedAudio7.src = '" + game.treeleaves + "'; "
      game.preload_leaves = game.preload_leaves + "window.cachedAudio7.preload = 'auto'; "
      game.preload_leaves = game.preload_leaves + "window.cachedAudio7.load();"
      game.preload_leaves = game.preload_leaves + "window.cachedAudio7.loop = true; "
      JS.eval (game.preload_leaves)
      game.introoutro = "https://www.dropbox.com/scl/fi/hv4eq9cat9sy28wiua7qp/linktestoutrovers.mp3?rlkey=td2cj3gmewnddt3wdzq0mkufs&st=xj9rfcb8&raw=1"
      game.preload_inout = "window.cachedAudio8 = new Audio(); "
      game.preload_inout = game.preload_inout + "window.cachedAudio8.src = '" + game.introoutro + "'; "
      game.preload_inout = game.preload_inout + "window.cachedAudio8.preload = 'auto'; "
      game.preload_inout = game.preload_inout + "window.cachedAudio8.load();"
      JS.eval (game.preload_inout)
      game.aboutsnailsweeper = NewStringList()
      list add (game.aboutsnailsweeper, "Very few were ever even made. If this one were real, it might be the most exciting thing that ever happened to you. You've read everything there is to read about snailsweepers.")
      list add (game.aboutsnailsweeper, "Supposedly the original design actually swept up the trash and stored it in an extra-large storage nose. You think they made the right choice, going with a design that actually eats trash, but you wonder what the extra-large storage nose would have looked like.")
      list add (game.aboutsnailsweeper, "It won't outrun anyone, but it actually gets up to nearly twice the speed of an actual snail its size!")
      list add (game.aboutsnailsweeper, "Snailsweepers actually use less magic proportionate to their weight compared to machines being advertised today. To make Grazing Mode work, the underside has to be bow to stern living bristle. Supposedly it takes forever to cultivate properly. As a result, it doesn't strictly need to be magical throughout the chassis.")
      list add (game.aboutsnailsweeper, "You wonder how they got the lights to work. You're not sure what exactly is glowing or how that works without magic. You'd honestly thought the glowing was a magnets thing, but obviously that's not it.")
      list add (game.aboutsnailsweeper, "You wonder if you should even entertain the idea that this snailsweeper had belonged to someone else. You're pretty confident Calliope would be putting more than a few trees in your path if you were stealing something.")
      game.aboutyou = NewStringList()
      list add (game.aboutyou, "You wonder what your voice sounds like. You assume it's different from the last time you heard it.")
      list add (game.aboutyou, "You stare at the curtain until your eyes sting but your eyelids just keep getting wider.")
      list add (game.aboutyou, "You can feel the rumble of bristles breaking down trash beneath you, and you sort of wish you were out there belly-down on the ground, too.")
      list add (game.aboutyou, "You try to push the hair out of your face, but that just gets it in your eyes.")
      list add (game.aboutyou, "You wonder if you should've become a wizard. An empty magic tank is only the latest problem in your life that being a wizard could have solved.")
      list add (game.aboutyou, "You wish this thing had a tea kettle instead of a color wheel.")
      JS.eval ("window.SetFrameURL=function(url){var img=$('#questFrameImg');if(!img.length){img=$('<img id=\"questFrameImg\" />').css({display:'block',margin:'0 auto',maxWidth:'100%',maxHeight:'300px'}).appendTo('#divOutput');}img.attr('src',url).show();$('body').css('padding-top','300px');};")
    ]]></start>
    <turnscript name="PingFlux">
      <enabled />
      <script><![CDATA[
        if (player.PingBase  <= 0) {
          player.PingBase = 0
        }
        else if (player.PingBase > 120) {
          player.PingBase = player.PingBase + GetRandomInt(-10, -5)
        }
        else if (player.PingBase < 121) {
          player.PingBase = player.PingBase + GetRandomInt(-5, 5)
        }
      ]]></script>
    </turnscript>
  </game>
  <command name="drop">
    <pattern>drop #object#</pattern>
    <allow_all />
    <scope>inventory</scope>
    <script>
      if (multiple and ListCount(object) = 0) {
        msg (Template("NotCarryingAnything"))
      }
      else {
        foreach (obj, object) {
          if (not multiple or Contains(game.pov, obj)) {
            DoDrop (obj, multiple)
          }
        }
      }
    </script>
  </command>
  <command name="use">
    <pattern>use #object#</pattern>
    <script><![CDATA[
      if (HasScript(object, "use")) {
        do (object, "use")
      }
      else {
        if (GetBoolean(object, "use")) {
          candidates = CreateUseMenuList (object)
          if (ListCount(candidates) = 0) {
            msg (Template("NoObjectsAvailable"))
          }
          else {
            game.pov.usemenuobject = object
            if (HasString(object, "usemenuprompt")) {
              menucaption = object.usemenuprompt
            }
            else {
              menucaption = Template("UseOnMenu")
            }
            ShowMenu (menucaption, candidates, true) {
              if (result <> null) {
                HandleUseOn (game.pov.usemenuobject, GetObject(result))
                game.pov.usemenuobject = null
              }
            }
          }
        }
        else {
          msg (DynamicTemplate("CantUse", object))
        }
      }
    ]]></script>
  </command>
  <command name="undo">
    <pattern type="string">^undo$</pattern>
    <isundo />
    <script>
      undo
      game.suppressturnscripts = true
      if (GetBoolean (game, "gridmap")) {
        Grid_DrawPlayerInRoom (game.pov.parent)
      }
    </script>
  </command>
  <command name="look">
    <pattern type="string">^look$|^l$</pattern>
    <script>
      ShowRoomDescription
    </script>
  </command>
  <command name="lookdir">
    <pattern type="string"><![CDATA[^look (?<exit>north|east|south|west|northeast|northwest|southeast|southwest|out|up|down|n|e|s|w|ne|nw|se|sw|o|u|d)$]]></pattern>
    <script><![CDATA[
      if (HasScript(exit, "look")) {
        do (exit, "look")
      }
      else {
        message = DynamicTemplate("YouLooking",exit.alias)
        if (HasString(exit, "look")) {
          if (exit.look <> "") {
            message = exit.look
          }
        }
        if (exit.locked) {
          if (HasString(exit,"lockmessage")) {
            lockmessage = exit.lockmessage
          }
          else {
            lockmessage = Template("LockedExit")
          }
          msg (message+" "+lockmessage)
        }
        else {
          msg (message)
        }
      }
    ]]></script>
  </command>
  <command name="quit">
    <pattern type="string">^quit$</pattern>
    <script>
      finish
    </script>
  </command>
  <command name="go">
    <pattern type="string"><![CDATA[^go to (?<exit>.*)$|^go (?<exit>.*)$|^(?<exit>north|east|south|west|northeast|northwest|southeast|southwest|in|out|up|down|n|e|s|w|ne|nw|se|sw|o|u|d)$]]></pattern>
    <unresolved>{=WriteVerb(game.pov, "can't")} go there.</unresolved>
    <script>
      if (exit.visible) {
        if (exit.locked) {
          msg (exit.lockmessage)
        }
        else if (not TestExitGlobal(exit)) {
          // Do nothing, already handled
        }
        else if (exit.runscript) {
          if (HasScript(exit, "script")) {
            do (exit, "script")
          }
        }
        else if (exit.lookonly) {
          msg (Template("UnresolvedLocation"))
        }
        else {
          if (HasString(exit, "message")) {
            if (not exit.message = "") {
              if (game.clearscreenonroomenter) {
                game.currentexitmessage = exit.message
              }
              else {
                msg (exit.message)
              }
            }
          }
          game.pov.parent = exit.to
        }
      }
      else {
        msg (Template("UnresolvedLocation"))
      }
    </script>
  </command>
  <command name="open">
    <pattern>open #object#</pattern>
    <script>
      TryOpenClose (true, object)
    </script>
  </command>
  <command name="close">
    <pattern>close #object#</pattern>
    <script>
      TryOpenClose (false, object)
    </script>
  </command>
  <command name="put">
    <pattern type="string"><![CDATA[^(put|insert|place|drop) (?<object1>.*) (on to|onto|in to|into|on|in) (?<object2>.*)$]]></pattern>
    <scope>object1=inventory|object2=container</scope>
    <script>
      // put object1 in/on object 2
      canbedropped = true
      if (HasBoolean(object1, "drop")) {
        if (not object1.drop) {
          canbedropped = false
        }
      }
      if (object1.parent = object2) {
        msg (DynamicTemplate("AlreadyThere", object1))
      }
      else if (not ListContains(ScopeInventory(), object1)) {
        msg (DynamicTemplate("NotCarrying", object1))
      }
      else if (not canbedropped) {
        msg (DynamicTemplate("ObjectCannotBeStored", object1))
      }
      else if (not ListContains(ScopeReachable(), object1)) {
        msg (BlockingMessage(object1, ""))
      }
      else if (not ListContains(ScopeReachable(), object2)) {
        msg (BlockingMessage(object2, ""))
      }
      else if (not object2.container) {
        msg (Template("CannotDoThat"))
      }
      else if (not object2.isopen) {
        msg (DynamicTemplate("ObjectNotOpen", object2))
      }
      else if (ListContains(ListParents(object2), object1)) {
        msg (Template("CannotDoThat"))
      }
      else if (not TestDropGlobal(object1, "")) {
        // Do nothing, already handled
      }
      else {
        if (GetBoolean(object2, "hidechildren")) {
          object2.hidechildren = false
        }
        params = NewDictionary()
        dictionary add (params, "object", object1)
        dictionary add (params, "destination", object2)
        if (HasScript(object2, "addscript")) {
          do (object2, "addscript", params)
        }
        else if (HasScript(object1, "drop")) {
          do (object1, "drop", params)
        }
        else {
          object1.parent = object2
          msg (Template("Done"))
        }
      }
      // must be carrying object1
      // item cannot be dropped
      // object1 must not be inside a closed container
      // object2 must not be inside a closed container
      // object2 must be an open container or surface
      // object1 is inside object 2
    </script>
  </command>
  <command name="removefrom">
    <pattern type="string"><![CDATA[^(remove|take|get|eject) (?<object1>.*) (from|out of|off|out) (?<object2>.*)$]]></pattern>
    <scope>object1=contents|object2=container</scope>
    <script>
      // remove object1 from object2
      // if object2 does indeed contain object1, this is a synonym for "take object1"
      if (not Contains(object2, object1)) {
        msg (DynamicTemplate("ObjectDoesNotContain", object2, object1))
      }
      else {
        DoTake (object1, false)
      }
    </script>
  </command>
  <command name="givesingle">
    <pattern>give #object#</pattern>
    <script><![CDATA[
      if (HasScript(object, "givesingle")) {
        do (object, "givesingle")
      }
      else {
        if (GetBoolean(object, "givesingle")) {
          candidates = CreateGiveMenuList (object)
          if (ListCount(candidates) = 0) {
            msg (Template("NoObjectsAvailable"))
          }
          else {
            game.pov.givemenuobject = object
            if (HasString(object, "givemenuprompt")) {
              menucaption = object.givemenuprompt
            }
            else {
              menucaption = Template("GiveToMenu")
            }
            ShowMenu (menucaption, candidates, true) {
              if (result <> null) {
                HandleGiveTo (game.pov.givemenuobject, GetObject(result))
                game.pov.givemenuobject = null
              }
            }
          }
        }
        else {
          msg (DynamicTemplate("CantGive", object))
        }
      }
    ]]></script>
  </command>
  <command name="give">
    <pattern type="string"><![CDATA[^give (?<object1>.*) to (?<object2>.*)$]]></pattern>
    <script>
      HandleGiveTo (object1, object2)
    </script>
  </command>
  <command name="useon">
    <pattern type="string"><![CDATA[^use (?<object1>.*) (on|with) (?<object2>.*)$]]></pattern>
    <script>
      HandleUseOn (object1, object2)
    </script>
  </command>
  <command name="ask">
    <pattern type="string"><![CDATA[^ask (?<object>.*) about (?<text>.*)$]]></pattern>
    <script>
      DoAskTell (object, text, "ask", "askdefault", "DefaultAsk")
    </script>
  </command>
  <command name="tell">
    <pattern type="string"><![CDATA[^tell (?<object>.*) about (?<text>.*)$]]></pattern>
    <script>
      DoAskTell (object, text, "tell", "telldefault", "DefaultTell")
    </script>
  </command>
  <command name="tellto">
    <pattern type="string"><![CDATA[^(tell|ask) (?<object>.*) to (?<text>.*)$]]></pattern>
    <script>
      DoAskTell (object, text, "tellto", "telltodefault", "DefaultTellTo")
    </script>
  </command>
  <command name="alttellto">
    <pattern type="string"><![CDATA[^(?<object>.*), (?<text>.*)$]]></pattern>
    <script>
      DoAskTell (object, text, "tellto", "telltodefault", "DefaultTellTo")
    </script>
  </command>
  <command name="oops">
    <pattern type="string"><![CDATA[^oops (?<text>.*)$]]></pattern>
    <isoops />
    <script><![CDATA[
      hasoops = false
      if (HasAttribute(game, "unresolvedcommand")) {
        if (game.unresolvedcommand <> null) {
          hasoops = true
        }
      }
      if (not hasoops) {
        msg (Template("DefaultOops"))
      }
      else {
        dictionary remove (game.unresolvedcommandvarlist, game.unresolvedcommandkey)
        dictionary add (game.unresolvedcommandvarlist, game.unresolvedcommandkey, text)
        HandleSingleCommandPattern ("", game.unresolvedcommand, game.unresolvedcommandvarlist)
      }
      game.suppressturnscripts = true
    ]]></script>
  </command>
  <verb name="speak">
    <pattern>speak to #object#; speak #object#; talk to #object#; talk #object#</pattern>
    <property>speak</property>
    <defaulttemplate>DefaultSpeakTo</defaulttemplate>
  </verb>
  <verb name="buy">
    <pattern>buy #object#; purchase #object#</pattern>
    <property>buy</property>
    <defaulttemplate>DefaultBuy</defaulttemplate>
  </verb>
  <verb name="climb">
    <pattern>climb #object#</pattern>
    <property>climb</property>
    <defaulttemplate>DefaultClimb</defaulttemplate>
  </verb>
  <verb name="drink">
    <pattern>drink #object#</pattern>
    <property>drink</property>
    <defaulttemplate>DefaultDrink</defaulttemplate>
  </verb>
  <verb name="eat">
    <pattern>eat #object#</pattern>
    <property>eat</property>
    <defaulttemplate>DefaultEat</defaulttemplate>
  </verb>
  <verb name="enter">
    <pattern>enter #object#; go in #object#; go into #object#; get in #object#; get into #object#</pattern>
    <property>enterverb</property>
    <defaulttemplate>DefaultEnter</defaulttemplate>
  </verb>
  <verb name="hit">
    <pattern>hit #object#</pattern>
    <property>hit</property>
    <defaulttemplate>DefaultHit</defaulttemplate>
  </verb>
  <verb name="kill">
    <pattern>kill #object#</pattern>
    <property>kill</property>
    <defaulttemplate>DefaultKill</defaulttemplate>
  </verb>
  <verb name="kiss">
    <pattern>kiss #object#</pattern>
    <property>kiss</property>
    <defaulttemplate>DefaultKiss</defaulttemplate>
  </verb>
  <verb name="knock">
    <pattern>knock #object#</pattern>
    <property>knock</property>
    <defaulttemplate>DefaultKnock</defaulttemplate>
  </verb>
  <verb name="lick">
    <pattern>lick #object#</pattern>
    <property>lick</property>
    <defaulttemplate>DefaultLick</defaulttemplate>
  </verb>
  <verb name="lieon">
    <pattern>lie on #object#; lie upon #object#; lie down on #object#; lie down upon #object#</pattern>
    <property>lie</property>
    <defaulttemplate>DefaultLie</defaulttemplate>
  </verb>
  <verb name="listento">
    <pattern>listen to #object#</pattern>
    <property>listen</property>
    <defaulttemplate>DefaultListenTo</defaulttemplate>
  </verb>
  <verb name="lock">
    <pattern>lock #object#</pattern>
    <property>lock</property>
    <defaulttemplate>DefaultLock</defaulttemplate>
  </verb>
  <verb name="move">
    <pattern>move #object#</pattern>
    <property>move</property>
    <defaulttemplate>DefaultMove</defaulttemplate>
  </verb>
  <verb name="pull">
    <pattern>pull #object#</pattern>
    <property>pull</property>
    <defaulttemplate>DefaultPull</defaulttemplate>
  </verb>
  <verb name="push">
    <pattern>push #object#</pattern>
    <property>push</property>
    <defaulttemplate>DefaultPush</defaulttemplate>
  </verb>
  <verb name="read">
    <pattern>read #object#</pattern>
    <property>read</property>
    <defaulttemplate>DefaultRead</defaulttemplate>
  </verb>
  <verb name="show">
    <pattern>show #object#</pattern>
    <property>show</property>
    <defaulttemplate>DefaultShow</defaulttemplate>
  </verb>
  <verb name="siton">
    <pattern>sit on #object#; sit upon #object#; sit down on #object#; sit down upon #object#</pattern>
    <property>sit</property>
    <defaulttemplate>DefaultSit</defaulttemplate>
  </verb>
  <verb name="smell">
    <pattern>smell #object#; sniff #object#</pattern>
    <property>smell</property>
    <defaulttemplate>DefaultSmell</defaulttemplate>
  </verb>
  <verb name="taste">
    <pattern>taste #object#</pattern>
    <property>taste</property>
    <defaulttemplate>DefaultTaste</defaulttemplate>
  </verb>
  <verb name="throw">
    <pattern>throw #object#</pattern>
    <property>throw</property>
    <defaulttemplate>DefaultThrow</defaulttemplate>
  </verb>
  <verb name="tie">
    <pattern>tie #object#</pattern>
    <property>tie</property>
    <defaulttemplate>DefaultTie</defaulttemplate>
  </verb>
  <verb name="touch">
    <pattern>touch #object#</pattern>
    <property>touch</property>
    <defaulttemplate>DefaultTouch</defaulttemplate>
  </verb>
  <verb name="turnon">
    <pattern>turn on #object#; turn #object# on; switch on #object#; switch #object# on</pattern>
    <property>turnon</property>
    <defaulttemplate>DefaultTurnOn</defaulttemplate>
  </verb>
  <verb name="turnoff">
    <pattern>turn off #object#; turn #object# off; switch off #object#; switch #object# off</pattern>
    <property>turnoff</property>
    <defaulttemplate>DefaultTurnOff</defaulttemplate>
  </verb>
  <verb name="turn">
    <pattern>turn #object#</pattern>
    <property>turn</property>
    <defaulttemplate>DefaultTurn</defaulttemplate>
  </verb>
  <verb name="unlock">
    <pattern>unlock #object#</pattern>
    <property>unlock</property>
    <defaulttemplate>DefaultUnlock</defaulttemplate>
  </verb>
  <verb name="untie">
    <pattern>untie #object#</pattern>
    <property>untie</property>
    <defaulttemplate>DefaultUntie</defaulttemplate>
  </verb>
  <command name="listen">
    <pattern type="string">^listen$</pattern>
    <script>
      msg (Template("DefaultListen"))
    </script>
  </command>
  <command name="jump">
    <pattern type="string">^jump$</pattern>
    <script>
      msg (Template("DefaultJump"))
    </script>
  </command>
  <command name="sit">
    <pattern type="string">^sit$|^sit down$</pattern>
    <script>
      msg (Template("DefaultSitDown"))
    </script>
  </command>
  <command name="lie">
    <pattern type="string">^lie$|^lie down$</pattern>
    <script>
      msg (Template("DefaultLieDown"))
    </script>
  </command>
  <command name="sleep">
    <pattern type="string">^sleep$|^rest$</pattern>
    <script>
      msg (Template("DefaultSleep"))
    </script>
  </command>
  <command name="wait">
    <pattern type="string">^wait$|^z$</pattern>
    <script>
      msg (Template("DefaultWait"))
    </script>
  </command>
  <command name="xyzzy">
    <pattern type="string">^xyzzy$</pattern>
    <script>
      msg (Template("DefaultXyzzy"))
    </script>
  </command>
  <command name="help">
    <pattern type="string">^help$|^\?$</pattern>
    <script>
      msg (Template("DefaultHelp"))
      game.suppressturnscripts = true
    </script>
  </command>
  <command name="save">
    <pattern type="string">^save$</pattern>
    <script>
      request (RequestSave, "")
      SuppressTurnscripts
    </script>
  </command>
  <command name="version_cmd">
    <pattern type="string">^(version|info|about)$</pattern>
    <script><![CDATA[
      s = "<b>TITLE: </b>" + game.gamename + "<br/>"
      if (HasAttribute (game, "author")) {
        s = s + "<b>AUTHOR: </b>" + game.author + "<br/>"
      }
      s = s + "<b>VERSION: </b>" + game.version + "<br/>"
      s = s + "<b>IFID: </b>" + game.gameid + "<br/>"
      s = s + "<br/>"
      msg (s)
      game.suppressturnscripts = true
    ]]></script>
  </command>
  <command name="view_transcript_cmd">
    <pattern type="string">^(view|display|show) (the |)(script|transcript)$</pattern>
    <script>
      if (not GetBoolean(game, "notranscript")) {
        JS.showTranscript ()
      }
      else {
        msg (Template("NoTranscriptFeature"))
      }
      SuppressTurnscripts
    </script>
  </command>
  <command name="transcript_on_cmd">
    <pattern type="string">^(transcript|script)( on|)$|^enable (script|transcript)$</pattern>
    <script>
      if (not GetBoolean(game, "notranscript")) {
        if (not GetBoolean(game,"savetranscript")) {
          if (GetBoolean(game,"showcommandbar")) {
            msg (Template("TranscriptEnterFilename"))
            JS.loadTranscriptNameInputVal ()
            get input {
              filename = Trim(result)
              InitiateTranscript (filename)
            }
          }
          else {
            filename = GetWindowsSafeName(game.gamename)
            InitiateTranscript (filename)
          }
        }
        else {
          msg (Template("TranscriptAlreadyEnabled"))
        }
      }
      else {
        msg (Template("NoTranscriptFeature"))
      }
      SuppressTurnscripts
    </script>
  </command>
  <command name="transcript_off_cmd">
    <pattern type="string">^(transcript|script) off$|^disable (script|transcript)$</pattern>
    <script>
      if (not GetBoolean(game, "notranscript")) {
        if (GetBoolean(game,"savetranscript")) {
          DisableTranscript
          msg (Template("TranscriptDisabled"))
        }
        else {
          msg (Template("TranscriptAlreadyDisabled"))
        }
      }
      else {
        msg (Template("NoTranscriptFeature"))
      }
      SuppressTurnscripts
    </script>
  </command>
  <command name="restart">
    <pattern type="string">^restart$</pattern>
    <script>
      Ask (Template("WantRestartGame")) {
        if (result) {
          JS.eval ("if(webPlayer){window.location.reload();}else if (typeof(RestartGame) != 'undefined'){RestartGame();}else{addTextAndScroll('Try pressing CTRL+R.')};")
        }
        else {
          game.suppressturnscripts = true
        }
      }
    </script>
  </command>
  <command name="wear">
    <pattern>put #object# on; wear #object#; put on #object#; don #object#; wear #object#</pattern>
    <allow_all />
    <scope>inventory</scope>
    <script>
      if (multiple and ListCount(object) = 0) {
        msg (Template("NothingToWear"))
      }
      else {
        foreach (obj, object) {
          if (multiple) {
            OutputTextNoBr (GetDisplayAlias(obj) + ": ")
          }
          f = _DoWear(obj)
        }
        UpdateArmour
      }
    </script>
  </command>
  <command name="remove">
    <pattern>take #object# off; remove #object#; take off #object#; doff #object#</pattern>
    <allow_all />
    <scope>inventory</scope>
    <script>
      if (multiple and ListCount(object) = 0) {
        msg (Template("NothingToRemove"))
      }
      else {
        foreach (obj, object) {
          if (multiple) {
            OutputTextNoBr (GetDisplayAlias(obj) + ": ")
          }
          f = _DoRemove(obj)
        }
      }
      UpdateArmour
    </script>
  </command>
  <command name="devmode_commands">
    <pattern type="string"><![CDATA[^#(?<text>.*)]]></pattern>
    <script><![CDATA[
      if (HasAttribute(game, "devmode_active")) {
        if (game.devmode_active) {
          if (IsDefined("text")) {
            regex = "^(?<command2>put) (?<object1>.+) (in|on) (?<object2>.+)$|^(?<command1>drop|take|to|go|open|close|on|off) (?<object>.+)$|^(?<command0>selftest|clr|\\?)$"
            if (IsRegexMatch (regex, text)) {
              result = populate (regex, text)
              com0 = ToString(DictionaryItem(result, "command0"))
              com1 = ToString(DictionaryItem(result, "command1"))
              com2 = ToString(DictionaryItem(result, "command2"))
              // Commands
              if (not com0 = "") {
                switch (LCase(com0)) {
                  case ("selftest") {
                    selfTest
                  }
                  case ("clr") {
                    ClearScreen
                  }
                  case ("?") {
                    DevModeOutput (Template("DevModeDescriptionCommands"))
                  }
                }
              }
              else if (not com1 = "") {
                objstr = ToString(DictionaryItem(result, "object"))
                obj = getObjectExt(objstr)
                if (obj = null) {
                  error (DynamicTemplate("DevModeErrorCantFindObject", objstr))
                }
                switch (LCase(com1)) {
                  case ("drop") {
                    setWithoutChange (obj, "parent", game.pov.parent)
                    DevModeOutput (Template("DevModeComExecute"))
                  }
                  case ("take") {
                    setWithoutChange (obj, "parent", game.pov)
                    DevModeOutput (Template("DevModeComExecute"))
                  }
                  case ("to") {
                    setWithoutChange (game, "pov", obj)
                    DevModeOutput (Template("DevModeComExecute"))
                  }
                  case ("go") {
                    setWithoutChange (game.pov, "parent", obj)
                    DevModeOutput (Template("DevModeComExecute"))
                  }
                  case ("open") {
                    setWithoutChange (obj, "isopen", true)
                    DevModeOutput (Template("DevModeComExecute"))
                  }
                  case ("close") {
                    setWithoutChange (obj, "isopen", false)
                    DevModeOutput (Template("DevModeComExecute"))
                  }
                  case ("on") {
                    setWithoutChange (obj, "switchedon", true)
                    DevModeOutput (Template("DevModeComExecute"))
                  }
                  case ("off") {
                    setWithoutChange (obj, "switchedon", false)
                    DevModeOutput (Template("DevModeComExecute"))
                  }
                }
              }
              else if (not com2 = "") {
                obj1str = ToString(DictionaryItem(result, "object1"))
                obj2str = ToString(DictionaryItem(result, "object2"))
                obj1 = getObjectExt(obj1str)
                obj2 = getObjectExt(obj2str)
                if (obj1 = null) {
                  error (DynamicTemplate("DevModeErrorCantFindObject", obj1str))
                }
                if (obj2 = null) {
                  error (DynamicTemplate("DevModeErrorCantFindObject", obj2str))
                }
                switch (LCase(ToString(DictionaryItem(result, "command2")))) {
                  case ("put") {
                    setWithoutChange (obj1, "parent", obj2)
                    DevModeOutput (Template("DevModeComExecute"))
                  }
                }
              }
            }
            else {
              ParseToQuestCode (text)
            }
            // Expressions
          }
          else {
            request (Quit, "")
          }
        }
        else {
          error (Template("DevModeNotActive"))
        }
      }
      else {
        error (Template("DevModeNotActive"))
      }
    ]]></script>
  </command>
  <command name="inventory">
    <pattern type="string">^i$|^inv$|^inventory$</pattern>
    <script>
      // list = FormatObjectList(Template("CarryingListHeader"), game.pov, Template("And"), ".")
      // if (list = "") {
        // msg (Template("NotCarryingAnything"))
        // }
      // else {
        // msg (list)
        // }
    </script>
  </command>
  <command name="take">
    <pattern>take #object#; get #object#; pick up #object#</pattern>
    <allow_all />
    <scope>notheld</scope>
    <script>
      // took_something = false
      // foreach (obj, object) {
        // if this is multiple then we should skip anything in a container that has already been taken
        // (always earlier in the list) and anything held by an NPC.
        // Scenery and anything flagged "not_all" will already be excluded
        // if (not multiple or (not Contains(game.pov, obj.parent) and not DoesInherit(obj.parent, "npc_type"))) {
          // DoTake (obj, multiple)
          // took_something = true
          // }
        // }
      // if (multiple and not took_something) {
        // msg (Template("NothingToTake"))
        // }
    </script>
  </command>
  <verb name="search">
    <pattern>search #object#</pattern>
    <property>search</property>
    <defaulttemplate>DefaultSearch</defaulttemplate>
    <multiobjectmenuempty type="string"></multiobjectmenuempty>
    <multiobjectdefault type="string"></multiobjectdefault>
    <multiobjectmenu type="string"></multiobjectmenu>
  </verb>
  <command name="lookat">
    <pattern>look at #object#; look #object#; x #object#; </pattern>
    <script>
      if (GetBoolean(object, "hidechildren")) {
        object.hidechildren = false
      }
      if (TypeOf(object, "look") = "script") {
        if (not HasAttribute(object,"timesexamined")) {
          object.timesexamined = 0
        }
        do (object, "look")
        object.timesexamined = object.timesexamined + 1
      }
      else {
        lookdesc = ""
        if (HasString(object, "look")) {
          lookdesc = object.look
        }
        if (LengthOf(lookdesc) = 0) {
          lookdesc = Template("DefaultObjectDescription")
        }
        if (GetBoolean(object, "switchedon")) {
          if (HasString(object, "switchedondesc")) {
            lookdesc = lookdesc + " " + object.switchedondesc
          }
        }
        else {
          if (HasString(object, "switchedoffdesc")) {
            lookdesc = lookdesc + " " + object.switchedoffdesc
          }
        }
        isDark = CheckDarkness()
        if (isDark and not GetBoolean(object, "lightsource")) {
          lookdesc = DynamicTemplate("LookAtDarkness", object)
        }
        else {
          if (not HasAttribute(object,"timesexamined")) {
            object.timesexamined = 0
          }
          object.timesexamined = object.timesexamined + 1
        }
        msg (lookdesc)
      }
      ListObjectContents (object)
    </script>
  </command>
  <object name="cmd">
    <inherit name="editor_room" />
    <usedefaultprefix type="boolean">false</usedefaultprefix>
    <beforeenter type="script">
    </beforeenter>
    <enter type="script">
    </enter>
    <firstenter type="script"><![CDATA[
      game.boundary_lock = true
      cmd.visited = true
      msg ("Terminal ready")
      msg ("Loading configuration “nowhere_linktest”")
      SetTimeout (1) {
        msg ("Status: Initializing")
        msg ("Status: Dialing The Calliope")
        JS.eval ("window.cachedAudio0.play();")
        SetTimeout (5) {
          msg ("Status: Negotiating Protocol")
          SetTimeout (7) {
            msg ("CONNECT 56000")
            msg ("THE CALLIOPE")
            msg ("User: autoguest")
            msg ("Password: ****")
            msg ("Verification complete.")
            msg ("guest@THE_CALLIOPE:~$ connect “CALLIOPE_HOST”")
            OutputTextNoBr ("Connecting to ://calliope.vision/grottovale/nobody.chr/ …")
            SetTimeout (1) {
              OutputTextNoBr ("connected.")
              msg (" ")
              OutputTextNoBr ("Request sent, awaiting response …")
              SetTimeout (1) {
                msg ("... OK")
                msg ("Connection established to CALLIOPE_HOST")
                SetTimeout (1) {
                  ClearScreen
                  msg ("CALLIOPE_HOST login: guest")
                  msg (">You agree not to be alone. ")
                  msg (">YES/NO")
                  game.boundary_lock = false
                  BoundaryUnlock
                  get input {
                    if (LCase(result) = "yes") {
                      game.boundary_lock = true
                      BoundaryLock
                      msg ("[WELCOME TO THE CALLIOPE]")
                      SetTimeout (1) {
                        ClearScreen
                        SetAlignment ("center")
                        SetTimeout (1) {
                          SetTimeout (1) {
                            PrintCentered ("Tourist's Guide to Magic Words<br/>")
                            msg ("* [VERBS] and important [NOUNS] appear in brackets. You can't use one without the other.<br/><br/>* COMMANDS appear on their own. You use them on their own.<br/><br/>* You only need to type the words, not the brackets.<br/>")
                            PrintCentered (". . . .<br/>")
                            SetTimeout (1) {
                              msg ("<br/>If you want to know [ABOUT] a [HAT], you type:<br/>> about hat<br/><br/>Not all nouns will be in caps. If you want to know [ABOUT] the trees, you type:<br/>> about trees<br/><br/>If you're told to GET IN the snailsweeper, you type:<br/>> get in<br/><br/>")
                              PrintCentered (". . . .<br/>")
                              SetTimeout (1) {
                                SetTimeout (1) {
                                  PrintCentered ("<br/>Complimentary Magic Words<br/>")
                                  msg ("<br/>[ABOUT]<br/><br/>. . . . So you can understand things.<br/>. . . .* You may need to think [ABOUT] some things more than once.<br/><br/><br/>HELP<br/><br/>. . . . So you can remember your [VERBS] and COMMANDS.<br/>. . . .* You may need to remember some magic words for yourself.<br/><br/>")
                                  PrintCentered (". . . .<br/>")
                                  SetTimeout (1) {
                                    PrintCentered ("Complimentary Advice<br/>")
                                    msg ("<br/>Have care.<br/><br/>Be curious.<br/><br/>Linger.<br/><br/>Connect.<br/>")
                                    PrintCentered (". . . .<br/>")
                                    SetTimeout (1) {
                                      SetAlignment ("left")
                                      msg ("<br/>[Press any key to continue.]<br/>")
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                        JS.eval ("$('#endWaitDiv').hide();")
                        wait {
                          ClearScreen
                          JS.eval ("window.cachedAudio5.play();")
                          SetTimeout (17) {
                            SetWebFontName ("Press Start 2P")
                            SetAlignment ("center")
                            msg (" ")
                            msg (" ")
                            msg (" ")
                            msg (" ")
                            msg (" ")
                            msg (" ")
                            msg (" ")
                            msg (" ")
                            msg ("{color:red:[you must imagine calliope happy]}")
                            SetTimeout (1) {
                              ClearScreen
                              MoveObject (player, welcome)
                            }
                            SetAlignment ("left")
                          }
                        }
                      }
                    }
                    else {
                      SetTimeout (5) {
                        msg ("DISCONNECTED")
                        SetTimeout (2) {
                          finish
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    ]]></firstenter>
  </object>
  <object name="nowhere">
    <inherit name="editor_room" />
    <hugtrash>0</hugtrash>
    <enter type="script">
    </enter>
    <beforefirstenter type="script">
    </beforefirstenter>
    <firstenter type="script"><![CDATA[
      nowhere.visited = true
      game.helpstate = 0
      game.active_play_text = NewStringList()
      list add (game.nowhere_intro, "> You have a snailsweeper key around your neck. ")
      list add (game.nowhere_intro, ". . . .")
      list add (game.nowhere_intro, ". . . ?")
      list add (game.nowhere_intro, ". . . !")
      list add (game.nowhere_intro, "Your heart beats against the key. Silently.")
      list add (game.nowhere_intro, "You can see the snailsweeper in front of you.")
      list add (game.nowhere_intro, "Just the outline, but you can actually see it.")
      list add (game.nowhere_intro, ". . . .You're probably imagining it.")
      list add (game.nowhere_intro, "You touch it. ")
      list add (game.nowhere_intro, "Of course you touch it.")
      list add (game.nowhere_intro, "Visions in the dark, of course you could never find anything out here and just leave it alone.")
      list add (game.nowhere_intro, "Always have to get your hands on it.")
      list add (game.nowhere_intro, "No way around that impulse.")
      list add (game.nowhere_intro, "You’re just like that.")
      list add (game.nowhere_intro, ". . . . <br/>")
      list add (game.nowhere_intro, "The shell is nice and smooth. Freshly waxed.")
      list add (game.nowhere_intro, "The bristles feel firm and healthy.")
      list add (game.nowhere_intro, "When you put your hand against the hood, it’s even a little warm to the touch. ")
      list add (game.nowhere_intro, "It’s a snailsweeper.")
      list add (game.nowhere_intro, "It’s an actual snailsweeper, like in the advertising. ")
      list add (game.nowhere_intro, ". . . . No.")
      list add (game.nowhere_intro, "No no no no.")
      list add (game.nowhere_intro, "You know better than that. ")
      list add (game.nowhere_intro, "You could sniff out one of Calliope’s visions from the shores of the overhead sea.")
      list add (game.nowhere_intro, "A snailsweeper in the middle of nowhere?")
      list add (game.nowhere_intro, "How would they even get it here?")
      list add (game.nowhere_intro, "Snailsweepers are strictly somewhere-bound!")
      list add (game.nowhere_intro, "It’s a safety feature you can’t override no matter how stupid you are! ")
      list add (game.nowhere_intro, "And how would anyone even tow something like this?")
      list add (game.nowhere_intro, "They’re heavier empty than some salesdrivers’ walking machines are fully loaded!")
      list add (game.nowhere_intro, "Sure, with enough magic, you could probably haul one out of a canal if you had to.")
      list add (game.nowhere_intro, "But to drag one all the way out, off roads, where not even the moon would ever see it again?")
      list add (game.nowhere_intro, "An entire graduating class of wizards couldn’t pull off a prank like that.")
      list add (game.nowhere_intro, ". . . . And what would the joke even be?")
      list add (game.nowhere_intro, "Dragging a rare marvel of modern machinery like this out into the deep trash?")
      list add (game.nowhere_intro, "Treating it like some kind of worthless compacted fossil out there for nobody to find?")
      list add (game.nowhere_intro, "So fully lost that the tasteless joker would never be able to prove they’d done it?")
      list add (game.nowhere_intro, "Unless someone’s scrying on you right now?")
      list add (game.nowhere_intro, "As if that were even possible, out here.")
      list add (game.nowhere_intro, "You’d be surprised if there were more than six of these even still sweeping around Grotto Vale, and now someone has -")
      list add (game.nowhere_intro, "No.")
      list add (game.nowhere_intro, "Nobody’s done nothing.")
      list add (game.nowhere_intro, "It’s just another vision.")
      list add (game.nowhere_intro, "It’s not real.")
      list add (game.nowhere_intro, "The world will have to try harder than that to trick you.")
      list add (game.nowhere_intro, ". . . . ")
      list add (game.nowhere_intro, "You get in the driver’s seat.")
      list add (game.nowhere_intro, "Yes, you realize it’s just a vision of a driver’s seat.")
      list add (game.nowhere_intro, "So it’s a vision. Who are you trying to impress?")
      list add (game.nowhere_intro, "You climb up and. . . . ")
      list add (game.nowhere_intro, "> The snailsweeper starts to move!")
      list add (game.nowhere_intro, "You immediately climb back down. ")
      list add (game.nowhere_intro, "> The snailsweeper stops!")
      list add (game.nowhere_intro, "Right.")
      list add (game.nowhere_intro, "Snailsweepers with empty magic tanks have a grazing mode that automatically takes them back to the nearest signlight.")
      list add (game.nowhere_intro, "Grazing mode kicks in whenever there’s someone in the driver’s seat.")
      list add (game.nowhere_intro, ". . . . You suppose you could drive, couldn’t you?")
      list add (game.nowhere_intro, "You suppose you could just sit in the driver’s seat and let it graze its way out of the dark.")
      list add (game.nowhere_intro, "You suppose that you could just sit back all comfortable and wait out the last of the long night.")
      list add (game.nowhere_intro, "You suppose you could just blaze a big ol’ slime trail from nowhere back to somewhere!")
      list add (game.nowhere_intro, "You suppose you could even see the Vale in the swimming daylight again, is that it?")
      list add (game.nowhere_intro, "Is that what you suppose?")
      list add (game.nowhere_intro, "That’d be the day.")
      list add (game.nowhere_intro, ". . . . You’re going to need your stuff.")
      list add (game.nowhere_intro, "If you’re going to go hitching a ride to your doom with this random vision, you’re bringing all your personal trash with you.")
      list add (game.nowhere_intro, "The imaginary snailsweeper isn’t going anywhere without you, anyway.")
      list add (game.nowhere_intro, "You turn away from the snailsweeper toward the empty, shrunken dark.")
      list add (game.nowhere_intro, "You can’t see anything out there.")
      list add (game.nowhere_intro, "You fall to your knees.")
      list add (game.nowhere_intro, "You reach forward.")
      list add (game.nowhere_intro, "Your hands touch trash.")
      list add (game.nowhere_intro, "Your elbows touch trash.")
      list add (game.nowhere_intro, "Your shoulders touch trash.")
      list add (game.nowhere_intro, ". . . . ")
      list add (game.nowhere_intro, "This is the hard part.")
      list add (game.nowhere_intro, "There are some magic words you like to remember when you do this.")
      list add (game.nowhere_intro, "You’re going to say them in your heart like you mean it.")
      list add (game.nowhere_intro, "You’re going to say them until you’re finally done.")
      list add (game.nowhere_intro, "You’re going to say:")
      list add (game.nowhere_intro, "HUG THAT TRASH")
      foreach (item, game.nowhere_intro) {
        list add (game.active_play_text, item)
      }
      on ready {
        JS.eval ("window.cachedAudio1.loop = true; window.cachedAudio1.play();")
        anykey
      }
      game.after_dialogue_script => {
        game.move_counter = 0
        game.Boundary_Lock = false
        BoundaryUnlock
        JS.uiShow ("#txtCommandDiv")
      }
    ]]></firstenter>
    <beforeenter type="script">
    </beforeenter>
    <object name="Snailsweeper">
      <inherit name="container_closed" />
      <inherit name="editor_room_object" />
      <feature_container />
      <isopen />
      <open type="boolean">false</open>
      <close type="boolean">false</close>
      <usedefaultprefix />
      <contentsprefix>in which there is</contentsprefix>
      <transparent />
      <driverseat type="int">0</driverseat>
      <driverstext type="boolean">false</driverstext>
      <about type="script">
        on ready {
          aboutsnail
        }
      </about>
      <changedparent type="script">
        if (game.pov = this) {
          if (IsDefined("oldvalue")) {
            OnEnterRoom (oldvalue)
          }
          else {
            OnEnterRoom (null)
          }
          if (game.gridmap) {
            MergePOVCoordinates
          }
        }
        this.hasbeenmoved = true
        // 1. Run the "first time" script if the room hasn't been visited
        if (not GetBoolean(this.parent, "visited")) {
          if (HasScript(this.parent, "firstenter")) {
            do (this.parent, "firstenter")
          }
          set (this.parent, "visited", true)
        }
        // 2. Run the standard "after entering" script
        if (HasScript(this.parent, "enter")) {
          do (this.parent, "enter")
        }
        // 3. Show the new room description so the player sees the move
        ShowRoomDescription
      </changedparent>
      <firstenter type="script">
      </firstenter>
      <enter type="script"><![CDATA[
        JS.eval ("if (window.cachedAudio2) { window.cachedAudio2.pause(); window.cachedAudio2.currentTime = 0; }")
        if (game.admintools and game.shellventory="4" and game.pages="1" and not game.introcomplete) {
          game.inendconsoletrigger = true
          game.introcomplete = true
          JS.eval ("if (window.cachedAudio7) { window.cachedAudio7.pause(); window.cachedAudio7.currentTime = 0; }")
        }
        if (game.snailsweeper_visited) {
          game.Boundary_Lock = false
          BoundaryUnlock
          JS.uiShow ("#txtCommandDiv")
          safe_play = "if (window.cachedAudio1 && window.cachedAudio1.paused) { "
            safe_play = safe_play + "window.cachedAudio1.play(); "
            safe_play = safe_play + "}"
          JS.eval (safe_play)
          if (RandomChance(15)) {
            msg ("<br/>You can still hear the sound of leaves outside, reaching for you.<br/>")
          }
          else if (RandomChance(14)) {
            msg ("<br/>It smells a little like snails in here, but you’re getting used to it.<br/>")
          }
          else if (RandomChance(17)) {
            msg ("<br/>You see the curtain flutter heavily as a supple branch drags across it.<br/>")
          }
          else if (RandomChance(25)) {
            msg ("<br/>You can still smell the smell of leaves through the curtain. <br/>")
          }
          else if (RandomChance(33)) {
            msg ("<br/>Your head hits the canopy on your way out of the shell. It hurts a little, but you don’t react.<br/>")
          }
          else if (RandomChance(50)) {
            msg ("<br/>You settle into the driver’s seat and just breathe for a second. It’s a comfortable seat.<br/>")
          }
          else if (RandomChance(50)) {
            msg ("<br/>You tuck your arms in close, keeping your entire self behind the curtains.<br/>")
          }
          else {
            msg ("<br/>You feel the silent rumble of the snailsweeper grazing on crushed trash.<br/>")
          }
        }
        else {
          game.active_play_text = NewStringList()
          game.nowhere_intro = NewStringList()
          list add (game.nowhere_intro, "In the driver’s seat, there’s enough light coming from under the hood for you to look around. ")
          list add (game.nowhere_intro, "The seat is comfortable and well-cushioned, and it even has armrests. Those are a pleasant surprise.")
          list add (game.nowhere_intro, "The canopy is modest and practical, sporting middleweight curtains. It’s a smart choice. Heavy enough for privacy, but approachable enough not to seem rude.")
          list add (game.nowhere_intro, "The console and chassis seem like they’re carved from grove marble, but you’re pretty sure it’s a veneer. ")
          list add (game.nowhere_intro, "The cushion at your back has the Grull & Trawl hallmark embroidered onto it. ")
          list add (game.nowhere_intro, "You can already tell that this is a machine that was made with love and care. Whether it’s real or just a vision, for a moment you can’t help but feel settled and safe.<br/>")
          foreach (item, game.nowhere_intro) {
            list add (game.active_play_text, item)
          }
          on ready {
            anykey
            JS.eval ("window.cachedAudio1.loop = true; window.cachedAudio1.play();")
          }
          game.after_dialogue_script => {
            game.active_play_text = NewStringList()
            game.nowhere_intro = NewStringList()
            list add (game.nowhere_intro, "You've always wanted to drive one of these. ")
            list add (game.nowhere_intro, "Not that you'll be doing much actual driving, but still.")
            list add (game.nowhere_intro, "You'd be lying if you said it wasn't a pleasant vision.")
            list add (game.nowhere_intro, ".  . . . You have to admit, you thought you were lost way too deep for visions. Usually, you’d - ")
            list add (game.nowhere_intro, "There’s a tickle on your upper arm. ")
            list add (game.nowhere_intro, "Then another.")
            list add (game.nowhere_intro, "Then a broad swipe like someone’s petting you with an open book. ")
            list add (game.nowhere_intro, "There they are. ")
            list add (game.nowhere_intro, "You recognize this. It's the feeling of wind-blown tree leaves against your skin.")
            list add (game.nowhere_intro, "There’s even a phantom sound of them, flirting in the wind.")
            list add (game.nowhere_intro, "Of course, you don’t feel any wind. Just the leaves.")
            list add (game.nowhere_intro, "Calliope loves to grace you with visions of trees. ")
            list add (game.nowhere_intro, "In daylight places, she shows you jade foliage clinging off the fingers of tall armored trunks, reaching. ")
            list add (game.nowhere_intro, "In the long night, leaves brush against your shoulders and your face, your breath filled with the soothing, green smell of tree country. ")
            list add (game.nowhere_intro, "You’re not trying to be ungrateful about it. ")
            list add (game.nowhere_intro, "Most people have never even been to tree country, but you can’t seem to ever leave it.")
            list add (game.nowhere_intro, "You feel a leaf's edge scratch against your temple.")
            list add (game.nowhere_intro, "> You lower the curtains!")
            list add (game.nowhere_intro, "You can always [RAISE] the [CURTAINS] again, when you don’t hear the trees anymore.")
            list add (game.nowhere_intro, "Normally, you’d never close the driver’s curtains fully while the snailsweeper is in motion.")
            list add (game.nowhere_intro, "That would be completely irresponsible.")
            list add (game.nowhere_intro, "But it’s not like you have any real control over the situation.")
            list add (game.nowhere_intro, "And it's not as if you have any particular interest in the view.")
            list add (game.nowhere_intro, "At least this way, you don’t feel any leaves against your arms. ")
            list add (game.nowhere_intro, "Nothing is touching you gently on the shoulder at all, and nothing is what you feel.")
            list add (game.nowhere_intro, "You look down at the CONSOLE.")
            list add (game.nowhere_intro, "You see the [MAGIC LIGHT], the [RUN LEVER], the [TILT SHIFT], the [STEERING VALVES], the [NAV POINTER], the [COLOR WHEEL], and the [CLAVIATURE]. ")
            list add (game.nowhere_intro, "Most of it looks powered down, but you can still learn more [ABOUT] them.")
            foreach (item, game.nowhere_intro) {
              list add (game.active_play_text, item)
            }
            on ready {
              JS.eval ("window.cachedAudio7.loop = true; window.cachedAudio7.play();")
              anykey
            }
            game.after_dialogue_script => {
              game.Boundary_Lock = false
              BoundaryUnlock
              JS.uiShow ("#txtCommandDiv")
              game.consoleintro = 0
              game.snailsweeper_visited = true
              game.move_counter = 0
              EnableTurnScript (Intro Counter Snailsweeper)
            }
          }
        }
      ]]></enter>
      <displayverbs type="stringlist">
        <value>Look at</value>
        <value>Take</value>
        <value>Open</value>
        <value>Close</value>
      </displayverbs>
      <inventoryverbs type="stringlist">
        <value>Look at</value>
        <value>Use</value>
        <value>Drop</value>
        <value>Open</value>
        <value>Close</value>
      </inventoryverbs>
      <object name="Run Lever">
        <inherit name="editor_object" />
        <about type="script"><![CDATA[
          msg ("You grasp the lever and push it halfway to run, but nothing powers up. You don't know why you bothered. You push the lever back to stop anyway. Just for safety.<br/>")
          if (Contains (nowhere,Snailsweeper)) {
            game.move_counter = game.move_counter+1
          }
        ]]></about>
      </object>
      <object name="Tilt Shift">
        <inherit name="editor_object" />
        <about type="script"><![CDATA[
          msg ("Even if you could move this lever without magic, you wouldn't. That's how snails wind up flipped over on the side of the road.<br/>")
          if (Contains (nowhere,Snailsweeper)) {
            game.move_counter = game.move_counter+1
          }
        ]]></about>
      </object>
      <object name="Color Wheel">
        <inherit name="editor_object" />
        <color type="int">1</color>
        <about type="script"><![CDATA[
          msg ("Of all the useless custom features, why's it gotta come with a color wheel? <br/>. . . . You suppose you could give it a [SPIN], though.<br/>")
          if (Contains (nowhere,Snailsweeper)) {
            game.move_counter = game.move_counter+1
          }
        ]]></about>
        <spin type="script">
          if (RandomChance(19)) {
            JS.eval ("$('body').css('background-image', 'url(\"" + GetFileURL("calliopemarginwatching3.png") + "\")');")
            SetTimeout (2) {
              JS.eval ("$('body').css('background-image', 'url(\"" + GetFileURL("calliopemarginnormal3.png") + "\")');")
            }
          }
          else {
            if (Color Wheel.color = 1) {
              SetForegroundColour ("Crimson")
              on ready {
                msg ("You spun the color wheel!")
              }
              Color Wheel.color = 2
            }
            else if (Color Wheel.color = 2) {
              SetForegroundColour ("MediumPurple")
              on ready {
                msg ("You spun the color wheel!")
              }
              Color Wheel.color = 3
            }
            else if (Color Wheel.color = 3) {
              SetForegroundColour ("Cyan")
              on ready {
                msg ("You spun the color wheel!")
              }
              Color Wheel.color = 4
            }
            else if (Color Wheel.color = 4) {
              SetForegroundColour ("White")
              on ready {
                msg ("You spun the color wheel!")
              }
              Color Wheel.color = 1
            }
          }
        </spin>
      </object>
      <object name="Claviature">
        <inherit name="editor_object" />
        <alias>clavi; claviature</alias>
        <about type="script"><![CDATA[
          msg ("At least you already know how to type on one of these.<br/>")
          if (Contains (nowhere,Snailsweeper)) {
            game.move_counter = game.move_counter+1
          }
        ]]></about>
      </object>
      <object name="Steering Valves">
        <inherit name="editor_object" />
        <alias>Valves; Steering Valves</alias>
        <about type="script"><![CDATA[
          msg ("Two round handles positioned a comfortable distance apart. With magic, this is supposed to be a very intuitive system of steering. Without magic, you'd have to have the strength of a dozen giraffes to get these to budge.<br/>")
          if (Contains (nowhere,Snailsweeper)) {
            game.move_counter = game.move_counter+1
          }
        ]]></about>
      </object>
      <object name="Nav Pointer">
        <inherit name="editor_object" />
        <displayverbs type="stringlist" />
        <inventoryverbs type="stringlist" />
        <alias>Nav; Nav pointer</alias>
        <scenery type="boolean">false</scenery>
        <about type="script"><![CDATA[
          msg ("<br/>This is state-of-the-art navigation equipment, perfect for the serious Grotto Vale tourist. It's a little needle that always points North, no matter what, using the power of magnets.<br/><br/> ....Too bad there's no magic in the tank, or you could finally see a magnet in action for yourself. What a pity.<br/>")
          if (Contains (nowhere,Snailsweeper)) {
            game.move_counter = game.move_counter+1
          }
        ]]></about>
      </object>
      <object name="Magic Light">
        <inherit name="editor_object" />
        <visible />
        <about type="script"><![CDATA[
          msg ("Not even a flicker. You don't gotta look at a manual to know that means empty.<br/>")
          if (Contains (nowhere,Snailsweeper)) {
            game.move_counter = game.move_counter+1
          }
        ]]></about>
      </object>
      <object name="Shlvl One">
        <inherit name="container_closed" />
        <inherit name="editor_room_object" />
        <feature_container />
        <hidechildren type="boolean">false</hidechildren>
        <displayverbs type="stringlist" />
        <drop type="boolean">false</drop>
        <alias>Snailshell</alias>
        <usedefaultprefix type="boolean">false</usedefaultprefix>
        <visible />
        <isopen type="boolean">false</isopen>
        <onopen type="script"><![CDATA[
          if (game.shellventory="1") {
            game.active_play_text = NewStringList()
            list add (game.nowhere_intro, "You turn around.")
            list add (game.nowhere_intro, "You move the back cushion.")
            list add (game.nowhere_intro, "You reach your arm inside the hole.")
            list add (game.nowhere_intro, "You reach your face inside the hole.")
            list add (game.nowhere_intro, "You reach your ear inside the hole.")
            list add (game.nowhere_intro, "There sure is a whole lot of trash back here.")
            list add (game.nowhere_intro, "Some of it even looks like it’s yours.")
            list add (game.nowhere_intro, ". . . .")
            list add (game.nowhere_intro, "You see a [Fuzzy Ball of PRESERVATIVE].")
            list add (game.nowhere_intro, "You see a [Tube of INSPIRATION].")
            list add (game.nowhere_intro, "You wonder what that all's [ABOUT]....")
            list add (game.nowhere_intro, "....But there's a lot of other trash in here.")
            list add (game.nowhere_intro, "You could DIG into it a little, or just go back to the CONSOLE. ")
            foreach (item, game.nowhere_intro) {
              list add (game.active_play_text, item)
            }
            on ready {
              anykey
            }
            game.after_dialogue_script => {
              game.Boundary_Lock = false
              BoundaryUnlock
              JS.uiShow ("#txtCommandDiv")
            }
          }
          else if (game.shellventory="2") {
            MoveObject (Latest Pages, Shlvl One)
            MoveObject (Snailsweeper Operation Manual, Shlvl One)
            game.active_play_text = NewStringList()
            list add (game.nowhere_intro, "You turn around.")
            list add (game.nowhere_intro, "You move the back cushion.")
            list add (game.nowhere_intro, "You reach your arm inside the hole.")
            list add (game.nowhere_intro, "You reach your face inside the hole.")
            list add (game.nowhere_intro, "You reach your ear inside the hole.")
            list add (game.nowhere_intro, "There sure is a whole lot of trash back here.")
            list add (game.nowhere_intro, "Some of it even looks like it’s yours.")
            list add (game.nowhere_intro, ". . . .")
            list add (game.nowhere_intro, "You see a [Fuzzy Ball of PRESERVATIVE].")
            list add (game.nowhere_intro, "You see a [Tube of INSPIRATION].")
            list add (game.nowhere_intro, "You see an [Official Grull & Trawl Snailsweeper Operational MANUAL].")
            list add (game.nowhere_intro, "You see your [Latest PAGES].")
            list add (game.nowhere_intro, "You wonder what that all's [ABOUT]....")
            list add (game.nowhere_intro, "....But there's a lot of other trash in here.")
            list add (game.nowhere_intro, "You could DIG into it a little, or just go back to the CONSOLE. ")
            foreach (item, game.nowhere_intro) {
              list add (game.active_play_text, item)
            }
            on ready {
              anykey
            }
            game.after_dialogue_script => {
              game.Boundary_Lock = false
              BoundaryUnlock
              JS.uiShow ("#txtCommandDiv")
            }
          }
          else if (game.shellventory="3") {
            MoveObject (Hat with no eyes, Shlvl One)
            MoveObject (Pen Set, Shlvl One)
            game.active_play_text = NewStringList()
            list add (game.nowhere_intro, "You turn around.")
            list add (game.nowhere_intro, "You move the back cushion.")
            list add (game.nowhere_intro, "You reach your arm inside the hole.")
            list add (game.nowhere_intro, "You reach your face inside the hole.")
            list add (game.nowhere_intro, "You reach your ear inside the hole.")
            list add (game.nowhere_intro, "There sure is a whole lot of trash back here.")
            list add (game.nowhere_intro, "Some of it even looks like it’s yours.")
            list add (game.nowhere_intro, ". . . .")
            list add (game.nowhere_intro, "You see a [Fuzzy Ball of PRESERVATIVE].")
            list add (game.nowhere_intro, "You see a [Tube of INSPIRATION].")
            list add (game.nowhere_intro, "You see an [Official Grull & Trawl Snailsweeper Operational MANUAL].")
            list add (game.nowhere_intro, "You see your [Latest PAGES].")
            list add (game.nowhere_intro, "You wonder what that all's [ABOUT]....")
            list add (game.nowhere_intro, "....But there's a lot of other trash in here.")
            list add (game.nowhere_intro, "You could DIG into it a little, or just go back to the CONSOLE. ")
            foreach (item, game.nowhere_intro) {
              list add (game.active_play_text, item)
            }
            on ready {
              anykey
            }
            game.after_dialogue_script => {
              game.Boundary_Lock = false
              BoundaryUnlock
              JS.uiShow ("#txtCommandDiv")
            }
          }
          else if (game.shellventory="4") {
            MoveObject (Loobert Chewbert Boobert, Shlvl One)
            game.active_play_text = NewStringList()
            list add (game.nowhere_intro, "You reach yourself into the shell hole.")
            list add (game.nowhere_intro, "You grope around and find a few things:")
            list add (game.nowhere_intro, ". . . .")
            list add (game.nowhere_intro, "You see a [Fuzzy Ball of PRESERVATIVE].")
            list add (game.nowhere_intro, "You see a [Tube of INSPIRATION].")
            list add (game.nowhere_intro, "You see an [Official Grull & Trawl Snailsweeper Operational MANUAL].")
            list add (game.nowhere_intro, "You see your [Latest PAGES].")
            list add (game.nowhere_intro, "You see a [PEN and well].")
            list add (game.nowhere_intro, "You see a [HAT without eyes].")
            list add (game.nowhere_intro, "You see [LOOBERT CHEWBERT BOOBERT].")
            list add (game.nowhere_intro, "You wonder what that all's [ABOUT]....")
            list add (game.nowhere_intro, "....But there's a lot of other trash in here.")
            list add (game.nowhere_intro, "You could DIG into it a little, or just go back to the CONSOLE. ")
            foreach (item, game.nowhere_intro) {
              list add (game.active_play_text, item)
            }
            on ready {
              anykey
            }
            game.after_dialogue_script => {
              game.Boundary_Lock = false
              BoundaryUnlock
              JS.uiShow ("#txtCommandDiv")
            }
          }
        ]]></onopen>
        <inventoryverbs type="stringlist">
          <value>Look at</value>
          <value>Use</value>
          <value>Drop</value>
          <value>Open</value>
          <value>Close</value>
        </inventoryverbs>
        <object name="Fuzzy Ball of Preservative">
          <inherit name="editor_object" />
          <visible />
          <alias>Preservative; Ball; Preservative Ball; Fuzzy Ball; Fuzzy Preservative</alias>
          <yum type="int">0</yum>
          <about type="script">
            msg ("If it's growing fuzz, that means it's healthy! You wonder if there's anything to [EAT] in all this [PRESERVATIVE]. . . .")
          </about>
          <eat type="script"><![CDATA[
            game.Boundary_Lock = true
            BoundaryLock
            JS.uiHide ("#txtCommandDiv")
            on ready {
              if (Fuzzy Ball of Preservative.yum = 0) {
                game.active_play_text = NewStringList()
                list add (game.active_play_text, "You undo the heavyweight scarf around your mouth.")
                list add (game.active_play_text, "You unwrap the light heavyweight scarf around your mouth.")
                list add (game.active_play_text, "You uncinch the welterweight scarf around your mouth.")
                list add (game.active_play_text, "You untie the featherweight scarf around your mouth.")
                list add (game.active_play_text, "You reach into the Fuzzy Preservative Ball.")
                list add (game.active_play_text, ". . . . You pull out a crunchy dumpling! Yum.")
                list add (game.active_play_text, "You put all your scarves back over your mouth before you make a sound.")
                on ready {
                  anykeyp
                  set (Fuzzy Ball of Preservative, "yum", 1)
                }
              }
              else if (Fuzzy Ball of Preservative.yum = 1) {
                game.active_play_text = NewStringList()
                list add (game.active_play_text, "You undo the heavyweight scarf around your mouth.")
                list add (game.active_play_text, "You unwrap the light heavyweight scarf around your mouth.")
                list add (game.active_play_text, "You uncinch the welterweight scarf around your mouth.")
                list add (game.active_play_text, "You untie the featherweight scarf around your mouth.")
                list add (game.active_play_text, "You reach into the Fuzzy Preservative Ball.")
                list add (game.active_play_text, ". . . . You pull out a juicy fern! Yum.")
                list add (game.active_play_text, "You put all your scarves back over your mouth before you make a sound.")
                on ready {
                  anykeyp
                  set (Fuzzy Ball of Preservative, "yum", 2)
                }
              }
              else {
                game.active_play_text = NewStringList()
                list add (game.active_play_text, "You undo the heavyweight scarf around your mouth.")
                list add (game.active_play_text, "You unwrap the light heavyweight scarf around your mouth.")
                list add (game.active_play_text, "You uncinch the welterweight scarf around your mouth.")
                list add (game.active_play_text, "You untie the featherweight scarf around your mouth.")
                list add (game.active_play_text, "You reach into the Fuzzy Preservative Ball.")
                list add (game.active_play_text, ". . . . You pull out a waxy potato! Yum.")
                list add (game.active_play_text, "You put all your scarves back over your mouth before you make a sound.")
                on ready {
                  anykeyp
                  set (Fuzzy Ball of Preservative, "yum", 0)
                }
              }
            }
            game.after_dialogue_script => {
              game.Boundary_Lock = false
              BoundaryUnlock
              JS.uiShow ("#txtCommandDiv")
              BackToShell
            }
          ]]></eat>
        </object>
        <object name="Inspiration">
          <inherit name="editor_object" />
          <visible />
          <alias>Tube of Inspiration; tube; inspiration</alias>
          <uncorked type="int">0</uncorked>
          <about type="script">
            msg ("A worn out tube protecting some of your most cherished prints and art pieces. Some of these are campaign originals. You might have some real, actual snailsweeper ads in here! Maybe you should [UNCORK] this [TUBE] sometime.")
          </about>
          <uncork type="script"><![CDATA[
            if (Inspiration.uncorked = 0) {
              game.active_play_text = NewStringList()
              list add (game.active_play_text, "You remove the jumbo cork and pull out the first thing your hand touches.")
              list add (game.active_play_text, "It's an ad for Briefdish Browning's All-Occasion Multi Purpose Homestyle Preservative!")
              list add (game.active_play_text, ". . . . You've secretly always wondered if Briefdish Browning really does make a better perservative than the other guys.")
              list add (game.active_play_text, "You carefully roll it back up and put it back in the tube.")
              on ready {
                anykeyp
                set (Inspiration, "uncorked", 1)
                on ready {
                  BackToShell
                }
              }
            }
            else if (Inspiration.uncorked = 1) {
              game.active_play_text = NewStringList()
              list add (game.active_play_text, "You remove the jumbo cork and pull out the first thing your hand touches.")
              list add (game.active_play_text, "It's a Snailsweeper advertisement! Featuring its classic slogan:")
              list add (game.active_play_text, "\"As silent as its shadow.\"")
              list add (game.active_play_text, "Grull & Trawl had this campaign up and running before they had any working models, so it's not surprising this snailsweeper doesn't look much like the one in the ad.")
              list add (game.active_play_text, "You carefully roll it back up and put it back in the tube.")
              on ready {
                anykeyp
                set (Inspiration, "uncorked", 2)
                on ready {
                  BackToShell
                }
              }
            }
            else if (Inspiration.uncorked = 2) {
              game.active_play_text = NewStringList()
              list add (game.active_play_text, "You remove the jumbo cork and pull out the first thing your hand touches.")
              list add (game.active_play_text, "It's a Snailsweeper advertisement! Featuring its classic slogan:")
              list add (game.active_play_text, "\"Touring or detouring, as long as you're sweeping..\"")
              list add (game.active_play_text, "This campaign was so successful, it inspired popular adventure story \"Sweep That Snail!\", about a clueless yet well-meaning snailsweeper on his first bumbling journey around Grotto Vale.")
              list add (game.active_play_text, "There were at least two sequels that you know of, which were very well-received.")
              list add (game.active_play_text, "You'd heard about a play that was supposed to be quite a spectacle, but you never saw it.")
              list add (game.active_play_text, "You're glad they eventually made the machine, too.")
              list add (game.active_play_text, "You carefully roll it back up and put it back in the tube.")
              on ready {
                anykeyp
                set (Inspiration, "uncorked", 3)
                on ready {
                  BackToShell
                }
              }
            }
            else if (Inspiration.uncorked = 3) {
              firsttime {
                game.active_play_text = NewStringList()
                player.connection = player.connection+1
                list add (game.active_play_text, "You remove the jumbo cork and pull out the first thing your hand touches.")
                list add (game.active_play_text, "It's an old flyer the School of Public Harmony's board of tourism studies was handing out everywhere a while back.")
                list add (game.active_play_text, "It has the Architect, the Custodian, and the Webmaster in sillhoutte, looming over Diadem Borough.")
                list add (game.active_play_text, "It says:")
                list add (game.active_play_text, "\"Loom Large:")
                list add (game.active_play_text, "Diadem Borough.\"")
                list add (game.active_play_text, ". . . . You've heard they have a museum for pretty much everything there.")
                list add (game.active_play_text, "You used to daydream about going there and finding a museum about nothing.")
                list add (game.active_play_text, "Or maybe starting one.")
                list add (game.active_play_text, "You carefully roll it back up and put it back in the tube.")
                on ready {
                  anykeyp
                  set (Inspiration, "uncorked", 0)
                  on ready {
                    BackToShell
                  }
                }
              }
              otherwise {
                game.active_play_text = NewStringList()
                list add (game.active_play_text, "You remove the jumbo cork and pull out the first thing your hand touches.")
                list add (game.active_play_text, "It's an old flyer the School of Public Harmony's board of tourism studies was handing out everywhere a while back.")
                list add (game.active_play_text, "It has the Architect, the Custodian, and the Webmaster in sillhoutte, looming over Diadem Borough.")
                list add (game.active_play_text, "It says:")
                list add (game.active_play_text, "\"Loom Large:")
                list add (game.active_play_text, "Diadem Borough.\"")
                list add (game.active_play_text, ". . . . You've heard they have a museum for pretty much everything there.")
                list add (game.active_play_text, "You used to daydream about going there and finding a museum about nothing.")
                list add (game.active_play_text, "Or maybe starting one.")
                list add (game.active_play_text, "You carefully roll it back up and put it back in the tube.")
                on ready {
                  anykeyp
                  set (Inspiration, "uncorked", 0)
                  on ready {
                    BackToShell
                  }
                }
              }
            }
          ]]></uncork>
        </object>
      </object>
      <object name="Shlvl Two">
        <inherit name="editor_object" />
        <inherit name="container_closed" />
        <feature_container />
        <alias>Snailshell</alias>
        <displayverbs type="stringlist">
          <value>Look at</value>
          <value>Take</value>
          <value>Open</value>
          <value>Close</value>
        </displayverbs>
        <inventoryverbs type="stringlist">
          <value>Look at</value>
          <value>Use</value>
          <value>Drop</value>
          <value>Open</value>
          <value>Close</value>
        </inventoryverbs>
        <object name="Latest Pages">
          <inherit name="editor_object" />
          <visible />
          <firstpage />
          <about type="script">
            msg ("You haven't written in this journal in ages. You should [READ] the [Latest PAGES] to jog your memory.")
          </about>
          <read type="script"><![CDATA[
            if (Latest Pages.firstpage) {
              game.active_play_text = NewStringList()
              game.nowhere_intro = NewStringList()
              player.connection = player.connection+1
              list add (game.nowhere_intro, "The last few entries don't have a mooncount. You must have written them in the long night. It's been so long, you don't remember what you could have written.")
              list add (game.nowhere_intro, "You start to read the first moonless entry:")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykey
              }
              game.after_dialogue_script => {
                game.active_play_text = NewStringList()
                game.nowhere_intro = NewStringList()
                list add (game.nowhere_intro, "You actually found the onion grove.")
                list add (game.nowhere_intro, "You laughed at the first sight of them.")
                list add (game.nowhere_intro, "Silently! Of course, silently. ")
                list add (game.nowhere_intro, "But of course you laughed.")
                list add (game.nowhere_intro, "They were so completely wrong about you. ")
                list add (game.nowhere_intro, "Onions can be wrong, after all.")
                list add (game.nowhere_intro, "You were only lost for a moment, after all.")
                list add (game.nowhere_intro, "You were on your way back to the signlight, after all.")
                list add (game.nowhere_intro, "You were getting out of here, after all.")
                list add (game.nowhere_intro, "But the time wore thin as the dew.")
                list add (game.nowhere_intro, "And in the humid warmth of the Vale, your bones grew cold.")
                list add (game.nowhere_intro, "And the time came when one of the onions….")
                list add (game.nowhere_intro, "….offered you a hug. ")
                list add (game.nowhere_intro, ". . . . ")
                list add (game.nowhere_intro, "You had always thought you would say no.")
                list add (game.nowhere_intro, "You had always thought. . . . ")
                list add (game.nowhere_intro, ". . . . ")
                list add (game.nowhere_intro, "When you finally pulled away, you couldn’t see the signlight anymore.")
                list add (game.nowhere_intro, "When you finally pulled away, it was dark.")
                list add (game.nowhere_intro, "When you finally pulled away, you were already gone.")
                list add (game.nowhere_intro, "You keep finding onions growing in your pockets.")
                list add (game.nowhere_intro, "You think everyone would smell them on you, if anyone were around.")
                list add (game.nowhere_intro, "Everyone would know.")
                foreach (item, game.nowhere_intro) {
                  list add (game.active_play_text, item)
                }
                on ready {
                  JS.eval ("window.cachedAudio4.play();")
                  SetFontName ("'Palatino Linotype', 'Book Antiqua', Palatino, serif")
                  SetFontSize (16)
                  anykeyp
                  game.pages = "1"
                }
                game.after_dialogue_script => {
                  game.active_play_text = NewStringList()
                  game.nowhere_intro = NewStringList()
                  list add (game.nowhere_intro, ". . . . ")
                  list add (game.nowhere_intro, "Your eyes aren't used to all this reading.")
                  list add (game.nowhere_intro, "They sort of sting.")
                  list add (game.nowhere_intro, "Maybe you'll read the rest of these pages later.")
                  foreach (item, game.nowhere_intro) {
                    list add (game.active_play_text, item)
                  }
                  on ready {
                    SetWebFontName ("Press Start 2P")
                    SetFontSize (12)
                    anykey
                    game.pages = "1"
                  }
                  game.after_dialogue_script => {
                    game.Boundary_Lock = false
                    BoundaryUnlock
                    JS.uiShow ("#txtCommandDiv")
                    set (Latest Pages, "firstpage", false)
                    game.pages = "1"
                    BackToShell
                    on ready {
                      JS.eval ("if (window.cachedAudio4) { window.cachedAudio4.pause(); window.cachedAudio4.currentTime = 0; }")
                    }
                  }
                }
              }
            }
            else {
              msg ("You don't think you can handle reading more just yet.")
              game.pages = "1"
            }
          ]]></read>
        </object>
        <object name="Snailsweeper Operation Manual">
          <inherit name="editor_object" />
          <inherit name="container_closed" />
          <visible />
          <alias>Manual</alias>
          <usedefaultprefix type="boolean">false</usedefaultprefix>
          <feature_container />
          <open />
          <admintools type="boolean">false</admintools>
          <readresponse>0</readresponse>
          <about type="script">
            if (Snailsweeper Operation Manual.readresponse = "3") {
              msg ("The stupid front cover won't stay down anymore. ")
            }
            else {
              msg ("The binding looks like it's never been opened. Probably because manuals are stupid and there's no reason for anyone to ever [READ] them.")
            }
          </about>
          <read type="script"><![CDATA[
            if (Snailsweeper Operation Manual.readresponse="0") {
              game.helpstate = 31
              game.active_play_text = NewStringList()
              game.nowhere_intro = NewStringList()
              list add (game.nowhere_intro, "[READ] the [MANUAL]?")
              list add (game.nowhere_intro, "Doesn't seem worth the eye strain.")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykey
              }
              game.after_dialogue_script => {
                game.Boundary_Lock = false
                BoundaryUnlock
                JS.uiShow ("#txtCommandDiv")
                set (Snailsweeper Operation Manual, "readresponse", "1")
              }
            }
            else if (Snailsweeper Operation Manual.readresponse ="1") {
              game.helpstate = 31
              game.active_play_text = NewStringList()
              game.nowhere_intro = NewStringList()
              list add (game.nowhere_intro, "Why in all the Calliope would you ever [READ] a [MANUAL]?")
              list add (game.nowhere_intro, "The snailsweeper doesn't need you micromanaging it.")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykey
              }
              game.after_dialogue_script => {
                game.Boundary_Lock = false
                BoundaryUnlock
                JS.uiShow ("#txtCommandDiv")
                set (Snailsweeper Operation Manual, "readresponse", "2")
              }
            }
            else if (Snailsweeper Operation Manual.readresponse ="2") {
              game.helpstate = 31
              game.active_play_text = NewStringList()
              game.nowhere_intro = NewStringList()
              player.curiosity = player.curiosity+5
              list add (game.nowhere_intro, ". . . .")
              list add (game.nowhere_intro, ". . . .")
              list add (game.nowhere_intro, ". . . ?")
              list add (game.nowhere_intro, ". . . . You open the manual. ")
              list add (game.nowhere_intro, "In the dim glow of the snailsweeper, you can make out some of the [TABLE] of contents. ")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykey
              }
              game.after_dialogue_script => {
                game.Boundary_Lock = false
                BoundaryUnlock
                JS.uiShow ("#txtCommandDiv")
                set (Snailsweeper Operation Manual, "readresponse", "3")
                on ready {
                  SetFontName ("'Courier New', Courier, monospace")
                  SetFontSize (16)
                  msg ("[TABLE of Contents] <br/>[GETTING STARTED]<br/>[REALITY TESTING]<br/>[Magic WORDS]<br/>[ADMINistrator TOOLS]<br/>")
                  HelperOpenObject (Snailsweeper Operation Manual)
                }
                on ready {
                  SetWebFontName ("Press Start 2P")
                  SetFontSize (12)
                  on ready {
                    msg ("You can [FLIP TO] any of these, or you can [RETURN] the [MANUAL] to the shell.")
                  }
                }
              }
            }
            else if (Snailsweeper Operation Manual.readresponse ="3") {
              game.helpstate = 31
              msg ("You open the Snailsweeper Manual.<br/>")
              SetFontName ("'Courier New', Courier, monospace")
              SetFontSize (16)
              msg ("[TABLE of Contents] <br/>[GETTING STARTED]<br/>[REALITY TESTING]<br/>[Magic WORDS]<br/>[ADMINistrator TOOLS]<br/>")
              SetWebFontName ("Press Start 2P")
              SetFontSize (12)
              msg ("You can [FLIP TO] any of these, or you can [RETURN] the [MANUAL] to the shell.")
              HelperOpenObject (Snailsweeper Operation Manual)
            }
          ]]></read>
          <return type="script"><![CDATA[
            if (game.shellventory="4") {
              HelperCloseObject (Snailsweeper Operation Manual)
              HelperOpenObject (Shlvl One)
              MoveObject (Snailsweeper Operation Manual, Shlvl One)
              MoveObject (Latest Pages, Shlvl One)
              MoveObject (Pen Set, Shlvl One)
              MoveObject (Hat with no eyes, Shlvl One)
              MoveObject (Loobert Chewbert Boobert, Shlvl One)
              game.active_play_text = NewStringList()
              game.nowhere_intro = NewStringList()
              game.helpstate = 2
              list add (game.nowhere_intro, "You're just staring at your own trash again.")
              list add (game.nowhere_intro, "[Fuzzy ball of PRESERVATIVE] <br/>[Tube of INSPIRATION]<br/>[Official Grull & Trawl Snailsweeper Operation MANUAL] <br/>[Latest PAGES] <br/>[PEN and well] <br/>[HAT without eyes] <br/>[LOOBERT CHEWBERT BOOBERT]<br/>")
              list add (game.nowhere_intro, "You can go back to the CONSOLE when you're done.")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykey
              }
              game.after_dialogue_script => {
                game.Boundary_Lock = false
                BoundaryUnlock
                JS.uiShow ("#txtCommandDiv")
              }
            }
            else {
              HelperCloseObject (Snailsweeper Operation Manual)
              HelperOpenObject (Shlvl One)
              MoveObject (Snailsweeper Operation Manual, Shlvl One)
              MoveObject (Latest Pages, Shlvl One)
              game.helpstate = 3
              game.active_play_text = NewStringList()
              game.nowhere_intro = NewStringList()
              list add (game.nowhere_intro, "Now you're just staring at your own trash again.")
              list add (game.nowhere_intro, "[Fuzzy ball of PRESERVATIVE] <br/>[Tube of INSPIRATION]<br/>[Official Grull & Trawl Snailsweeper Operation MANUAL] <br/>[Latest PAGES] <br/>")
              list add (game.nowhere_intro, "You can dig DEEP into the trash, and you can go back to the CONSOLE when you're done.")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykey
              }
              game.after_dialogue_script => {
                game.Boundary_Lock = false
                BoundaryUnlock
                JS.uiShow ("#txtCommandDiv")
              }
            }
          ]]></return>
          <displayverbs type="stringlist">
            <value>Look at</value>
            <value>Take</value>
            <value>Open</value>
            <value>Close</value>
          </displayverbs>
          <inventoryverbs type="stringlist">
            <value>Look at</value>
            <value>Use</value>
            <value>Drop</value>
            <value>Open</value>
            <value>Close</value>
          </inventoryverbs>
          <object name="TABLE">
            <inherit name="editor_object" />
            <flipto type="script"><![CDATA[
              SetFontName ("'Courier New', Courier, monospace")
              SetFontSize (16)
              msg ("[TABLE of Contents] <br/><br/>[GETTING STARTED]<br/>[REALITY TESTING]<br/>[Magic WORDS]<br/>[ADMINistrator TOOLS]<br/>")
              SetWebFontName ("Press Start 2P")
              SetFontSize (12)
              on ready {
                msg ("You can [FLIP TO] any of these, or you can [RETURN] the [MANUAL] to the shell.")
              }
            ]]></flipto>
          </object>
          <object name="GETTING STARTED">
            <inherit name="editor_object" />
            <flipto type="script"><![CDATA[
              SetFontName ("'Courier New', Courier, monospace")
              SetFontSize (16)
              game.active_play_text = NewStringList()
              game.nowhere_intro = NewStringList()
              list add (game.nowhere_intro, "GETTING STARTED<br/><br/>Congratulations on your new Grull & Trawl Snailform Sweeping Machine (“Snailsweeper”)!<br/>The Snailsweeper was especially developed with the Grotto Vale tourist in mind. With its built-in state-of-the-art navigation technology and unmatched magical efficiency, the risks and fears of travelling in the undersea can finally be a thing of the past. With this machine, you are safe from such perils as:<br/>")
              list add (game.nowhere_intro, ". . . . beguilement by lantern sirens,<br/>. . . . entrapment by shifting piles of fossil-trash,<br/>. . . . loss of self and mind in the moonless dark,<br/>. . . . debilitation by a lack of support on lonely travels.<br/><br/>As you explore the warm haven of the Calliope’s deepest, oldest valley, your Snailsweeper will emit a vision-friendly glow that allows for nearly-unobstructed sight in traditionally sightless locales. This will allow you to observe as your Snailsweeper consumes any and all unwanted trash in its path. The Snailsweeper is rated for consumption of both ancient fossil-trash and modern debris. It will passively convert either one into clean, pure magic, keeping your magic tank topped off for longer, uninterrupted adventures.")
              list add (game.nowhere_intro, "<br/>Each Snailsweeper has been rigorously tested in the shadows of Grotto Vale to ensure a frictionless and silent sweeping experience. Every Snailsweeper, yours included, carries the Grull & Trawl promise of silence and safety. While walking machines and wheeled carriages make too much noise to travel among the visions in the Vale, the Snailsweeper runs completely silent.")
              list add (game.nowhere_intro, "<br/>Whether you are a leisure tourist or a seasoned salesdriver, whether you want to see the sights or simply clean them up, you will love your Snailsweeper!<br/>To get started, ensure that your Snailsweeper is fully powered off with a full magic tank. <br/><br/>Next. . . .<br/>")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykeyp
              }
              game.after_dialogue_script => {
                game.active_play_text = NewStringList()
                game.nowhere_intro = NewStringList()
                list add (game.nowhere_intro, "You’re not straining your eyes to read instructions you can’t even follow. ")
                list add (game.nowhere_intro, "You can [FLIP TO] the [TABLE of contents], or you can [RETURN] the [MANUAL] to the shell. ")
                foreach (item, game.nowhere_intro) {
                  list add (game.active_play_text, item)
                }
                on ready {
                  SetWebFontName ("Press Start 2P")
                  SetFontSize (12)
                  anykey
                }
                game.after_dialogue_script => {
                  game.Boundary_Lock = false
                  BoundaryUnlock
                  JS.uiShow ("#txtCommandDiv")
                }
              }
            ]]></flipto>
          </object>
          <object name="REALITY TESTING">
            <inherit name="editor_object" />
            <flipto type="script"><![CDATA[
              SetFontName ("'Courier New', Courier, monospace")
              SetFontSize (16)
              game.active_play_text = NewStringList()
              game.nowhere_intro = NewStringList()
              list add (game.nowhere_intro, "REALITY TESTING<br/><br/>In some use cases, it may become necessary to determine whether or not your snailsweeper is real. Grotto Vale is mysterious, and Calliope’s visions can be very convincing.<br/>In such circumstances, reality testing may be conducted by calm and rational evaluation of the following criteria:<br/>")
              list add (game.nowhere_intro, "Real snailsweepers. . . .<br/><br/>. . . . run on real magic only.<br/>. . . . consume real trash and valley detritus in their path.<br/>. . . . sweep toward real somewheres only.<br/>. . . . require a real driver in order to move.<br/>")
              list add (game.nowhere_intro, "Visions of snailsweepers. . . .<br/><br/>. . . . run on real or imaginary magic.<br/>. . . . consume visions of trash and valley detritus.<br/>. . . . sweep toward other visions only.<br/>. . . . require a driver, but they do not have to be real.<br/>")
              list add (game.nowhere_intro, "If you are still uncertain if your machine is a real Grull & Trawl creation or merely a creation of Calliope’s imagination, you may:<br/>. . . . contact your system administrator, or<br/>. . . . seek a certified mechanist at a Grull & Trawl service station.*<br/><br/>*Look for signs for the Grull & Trawl Limited Flagship Operatory in Diadem Borough.<br/>")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykeyp
              }
              game.after_dialogue_script => {
                SetWebFontName ("Press Start 2P")
                SetFontSize (12)
                game.active_play_text = NewStringList()
                game.nowhere_intro = NewStringList()
                list add (game.nowhere_intro, "You can [FLIP TO] the [TABLE of contents], or you can [RETURN] the [MANUAL] to the shell. ")
                foreach (item, game.nowhere_intro) {
                  list add (game.active_play_text, item)
                }
                on ready {
                  anykey
                }
                game.after_dialogue_script => {
                  game.Boundary_Lock = false
                  BoundaryUnlock
                  JS.uiShow ("#txtCommandDiv")
                }
              }
            ]]></flipto>
          </object>
          <object name="MAGIC WORDS">
            <inherit name="editor_object" />
            <flipto type="script"><![CDATA[
              if (Snailsweeper Operation Manual.admintools) {
                SetFontName ("'Courier New', Courier, monospace")
                SetFontSize (16)
                game.admintools = true
                game.active_play_text = NewStringList()
                game.nowhere_intro = NewStringList()
                list add (game.nowhere_intro, "MAGIC WORDS <br/><br/>>Administrator Detected!<br/><br/>Safe Mode Detected!")
                list add (game.nowhere_intro, "Caution: You may experience longer-than-average loading times due to the limitations of Grazing Mode.<br/>")
                list add (game.nowhere_intro, "Caution: As always, use magic words intentionally and with care for optimal results.<br/>")
                list add (game.nowhere_intro, "Caution: Administrator Magic Words are for advanced users only! Please contact your System Administrator if you are in need of guidance past this point!<br/>")
                list add (game.nowhere_intro, "<br/>MAGIC WORDS for ADVANCED USERS ONLY:<br/>")
                list add (game.nowhere_intro, "ARE YOU OKAY<br/>")
                list add (game.nowhere_intro, ". . . .")
                list add (game.nowhere_intro, ". . . .")
                foreach (item, game.nowhere_intro) {
                  list add (game.active_play_text, item)
                }
                on ready {
                  anykeyp
                }
                game.after_dialogue_script => {
                  SetWebFontName ("Press Start 2P")
                  SetFontSize (12)
                  game.active_play_text = NewStringList()
                  game.nowhere_intro = NewStringList()
                  list add (game.nowhere_intro, ". . . .")
                  list add (game.nowhere_intro, "Seems like the rest of the page is still loading.")
                  list add (game.nowhere_intro, "Could take hours.")
                  list add (game.nowhere_intro, "Maybe days.")
                  list add (game.nowhere_intro, "You can [FLIP TO]  the [TABLE of contents], or you can [RETURN] the [MANUAL] to the shell. ")
                  foreach (item, game.nowhere_intro) {
                    list add (game.active_play_text, item)
                  }
                  on ready {
                    anykey
                  }
                  game.after_dialogue_script => {
                    game.Boundary_Lock = false
                    BoundaryUnlock
                    JS.uiShow ("#txtCommandDiv")
                  }
                }
              }
              else {
                SetFontName ("'Courier New', Courier, monospace")
                SetFontSize (16)
                msg ("MAGIC WORDS <br/><br/>Please contact your System Administrator for access to this page.<br/>")
                game.active_play_text = NewStringList()
                game.nowhere_intro = NewStringList()
                list add (game.nowhere_intro, "You can [FLIP TO]  the [TABLE of contents], or you can [RETURN] the [MANUAL] to the shell. ")
                foreach (item, game.nowhere_intro) {
                  list add (game.active_play_text, item)
                }
                on ready {
                  SetWebFontName ("Press Start 2P")
                  SetFontSize (12)
                  anykey
                }
                game.after_dialogue_script => {
                  game.Boundary_Lock = false
                  BoundaryUnlock
                  JS.uiShow ("#txtCommandDiv")
                }
              }
            ]]></flipto>
          </object>
          <object name="ADMINISTRATOR TOOLS">
            <inherit name="editor_object" />
            <alias>ADMIN TOOLS; ADMINISTRATOR TOOLS</alias>
            <flipto type="script"><![CDATA[
              SetFontName ("'Courier New', Courier, monospace")
              SetFontSize (16)
              game.active_play_text = NewStringList()
              game.nowhere_intro = NewStringList()
              list add (game.nowhere_intro, "ADMINISTRATOR TOOLS<br/>Caution! Administrator Tools are for Advanced Users Only! <br/>If you are not the System Administrator, you are advised to skip this section. <br/>If you are the System Administrator, please proceed . . . . <br/>")
              list add (game.nowhere_intro, "Accessing Administrator Mode<br/>1. Position yourself in the driver’s seat.<br/>2. Ensure the Magic Light is not empty or nearly empty.<br/>3. Locate the Claviature in your machine’s console.<br/>4. Using your fingers or chosen apparatus, type in your Administrator Password.<br/>5. Wait for five seconds.<br/>6. Reset the Run lever to the Stop position.<br/>7. Immediately reset the Run lever halfway to Run.<br/>8. You may now use Administrator Magic Words.<br/>")
              list add (game.nowhere_intro, "Accessing Administrator Tools in Grazing Mode<br/>1. Position yourself in the driver’s seat..<br/>2. Ensure that the Snailsweeper is currently in motion.<br/>3. Locate the Claviature in your machine’s console.<br/>4. Using your fingers or chosen apparatus, type in your Administrator Password.<br/>5. Your Snailsweeper should stop moving for approximately four calm heartbeats.<br/>6. Your Snailsweeper should begin moving again.<br/>7. You may now use Advanced Magic Words.<br/>Caution: Some Magic Words may be unavailable in Grazing Mode.<br/>")
              list add (game.nowhere_intro, "Setting and Resetting your Administrator Password<br/>1. Position yourself in the driver’s seat.<br/>2. Ensure that the Magic Light is not empty or near empty.<br/>3. Ensure that the Run lever is set at least halfway to Run.<br/>4. Place your key into the key drive.<br/>5. Keep your hands on the console during processing.<br/>6. When the key is returned to you, return it to its place on your body.<br/>7. Using your fingers or other apparatus, enter your new password on the Claviature, making sure to press “Enter” when you are done.<br/>8. You may now refer to instructions for Accessing Administrator Mode.<br/>")
              list add (game.nowhere_intro, "Setting and Resetting your Administrator Password in Grazing Mode.<br/>1. Changing of passwords in Grazing Mode is not permitted.<br/>2. Refer to instructions for Accessing [SAFE MODE].<br/>")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykeyp
              }
              firsttime {
                game.after_dialogue_script => {
                  game.active_play_text = NewStringList()
                  game.nowhere_intro = NewStringList()
                  list add (game.nowhere_intro, "Oh you have got to be - ")
                  list add (game.nowhere_intro, "Fine! If for some reason you absolutely must do this:")
                  list add (game.nowhere_intro, "You can [FLIP TO] the section on [SAFE MODE]. Or you can [FLIP TO] to the [TABLE of contents], if you for some unknowable reason want to keep reading this joke of a vision of a manual.")
                  list add (game.nowhere_intro, "Or you can [RETURN] the [MANUAL] to the shell. If only because of how completely irresponsible it would be to throw it away entirely.")
                  foreach (item, game.nowhere_intro) {
                    list add (game.active_play_text, item)
                  }
                  on ready {
                    SetWebFontName ("Press Start 2P")
                    SetFontSize (12)
                    anykey
                  }
                  game.after_dialogue_script => {
                    game.Boundary_Lock = false
                    BoundaryUnlock
                    JS.uiShow ("#txtCommandDiv")
                  }
                }
              }
              otherwise {
                game.after_dialogue_script => {
                  game.active_play_text = NewStringList()
                  game.nowhere_intro = NewStringList()
                  list add (game.nowhere_intro, "You can [FLIP TO] the section on [SAFE MODE]. Or you can [FLIP TO] to the [TABLE of contents]. ")
                  list add (game.nowhere_intro, "Or you can [RETURN] the [MANUAL] to the shell.")
                  foreach (item, game.nowhere_intro) {
                    list add (game.active_play_text, item)
                  }
                  on ready {
                    SetWebFontName ("Press Start 2P")
                    SetFontSize (12)
                    anykey
                  }
                  game.after_dialogue_script => {
                    game.Boundary_Lock = false
                    BoundaryUnlock
                    JS.uiShow ("#txtCommandDiv")
                  }
                }
              }
              game.admintoolsstart = true
            ]]></flipto>
          </object>
          <object name="SAFE MODE">
            <inherit name="editor_object" />
            <flipto type="script"><![CDATA[
              SetFontName ("'Courier New', Courier, monospace")
              SetFontSize (16)
              game.active_play_text = NewStringList()
              game.nowhere_intro = NewStringList()
              list add (game.nowhere_intro, "SAFE MODE<br/>Safe Mode is a utility unique to the Grull & Trawl Snailsweeper. It allows for fear-free travel to any corner of Grotto Vale, whether or not you have access to fresh magic to fill your tank. While magic is necessary for many of the Snailsweeper’s functions and features, critical features requiring Administrator access may be unlocked for use in Grazing Mode if absolutely necessary.<br/>")
              list add (game.nowhere_intro, "Caution: Initializing Safe Mode will require a password reset to access Administrator Tools upon refilling the magic tank.<br/>Caution: All Administrator Settings will be cleared and reset by this process.<br/>Caution: Safe Mode may only be initialized from Grazing Mode. Attempting to initialize Safe Mode with magic in the tank will provoke errors.<br/>")
              list add (game.nowhere_intro, "Initializing Safe Mode<br/>1. Position yourself in the driver’s seat.<br/>2. Ensure that your Snailsweeper is presently moving.<br/>3. Without removing it, [EXAMINE] your [KEY].<br/>4. Ensure that you have at least one token remaining.<br/>5. Ensure that your connection type is “PROMISE” or “PROMISE/SECURE.”<br/>6. Using your fingers or chosen apparatus, type “PROMISE” into the Claviature, making sure to press Enter.<br/>7. Using your fingers or chosen apparatus, type your Grull & Trawl Identification Number into the Claviature, omitting any zeros.<br/>8. The Snailsweeper will now generate your new promise contract. Caution: Failure to agree to your promise will still cost you one token from your key.<br/>9. Using your fingers or chosen apparatus, enter your response on the Claviature.<br/>10. Safe Mode is now initialized. Administrator Tools which do not require magic power are now unlocked.<br/>")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykeyp
              }
              game.after_dialogue_script => {
                game.active_play_text = NewStringList()
                game.nowhere_intro = NewStringList()
                list add (game.nowhere_intro, "You can [FLIP TO]  the [TABLE of contents], or you can [RETURN] the [MANUAL] to the shell. ")
                foreach (item, game.nowhere_intro) {
                  list add (game.active_play_text, item)
                }
                on ready {
                  SetWebFontName ("Press Start 2P")
                  SetFontSize (12)
                  anykey
                }
                game.after_dialogue_script => {
                  game.Boundary_Lock = false
                  BoundaryUnlock
                  JS.uiShow ("#txtCommandDiv")
                }
              }
              game.admintoolsstart = true
            ]]></flipto>
          </object>
        </object>
      </object>
      <object name="Shlvl Three">
        <inherit name="editor_object" />
        <inherit name="container_closed" />
        <feature_container />
        <alias>Snailshell</alias>
        <scenery type="boolean">false</scenery>
        <usedefaultprefix type="boolean">false</usedefaultprefix>
        <displayverbs type="stringlist">
          <value>Look at</value>
          <value>Take</value>
          <value>Open</value>
          <value>Close</value>
        </displayverbs>
        <inventoryverbs type="stringlist">
          <value>Look at</value>
          <value>Use</value>
          <value>Drop</value>
          <value>Open</value>
          <value>Close</value>
        </inventoryverbs>
        <object name="Hat with no eyes">
          <inherit name="editor_object" />
          <visible />
          <alias>hat with no eyes; hat</alias>
          <about type="script"><![CDATA[
            firsttime {
              msg ("You used to use it to hide from wizards, because if you can't see them, then they cant see you. You know that's true because no wizard has ever come up to you and told you that it isn't.<br/>")
              player.curiosity = player.curiosity+1
            }
            otherwise {
              msg ("You used to use it to hide from wizards, because if you can't see them, then they cant see you. You know that's true because no wizard has ever come up to you and told you that it isn't.<br/>")
            }
          ]]></about>
        </object>
        <object name="Pen Set">
          <inherit name="editor_object" />
          <alias>pen; pen and well; pen set</alias>
          <about type="script"><![CDATA[
            firsttime {
              msg ("The word well is still about half full, if you find a good reason to use it. <br/>")
              player.curiosity = player.curiosity+1
            }
            otherwise {
              msg ("The word well is still about half full, if you find a good reason to use it. <br/>")
            }
          ]]></about>
        </object>
      </object>
      <object name="itswarmdownhere">
        <inherit name="openable" />
        <inherit name="editor_room" />
        <feature_container />
        <isopen type="boolean">false</isopen>
        <alias>trash nest</alias>
        <enter type="script"><![CDATA[
          JS.eval ("if (window.cachedAudio1) { window.cachedAudio1.pause(); window.cachedAudio1.currentTime = 0; }")
          if (game.intro_ending) {
            game.active_play_text = NewStringList()
            game.nowhere_intro = NewStringList()
            game.helpstate = 8
            game.shellventory = "4"
            list add (game.nowhere_intro, "> The snailsweeper stops moving!")
            list add (game.nowhere_intro, "You burrow into your trash nest.")
            list add (game.nowhere_intro, "You clutch Loobert Chewbert Boobert gently.")
            list add (game.nowhere_intro, "You smoosh your face against his pigeon face.")
            list add (game.nowhere_intro, "You listen to the sound of no tree leaves touching your shoulder.")
            list add (game.nowhere_intro, "You breathe through your scarf. All you smell is onions.")
            list add (game.nowhere_intro, "Your arms fold around you.")
            list add (game.nowhere_intro, "This is the hard part.")
            list add (game.nowhere_intro, "You have to remember the magic words.")
            list add (game.nowhere_intro, "You have to say them in your heart like you mean them.")
            list add (game.nowhere_intro, "You have to say them until you're finally done.")
            list add (game.nowhere_intro, "Say them.")
            foreach (item, game.nowhere_intro) {
              list add (game.active_play_text, item)
            }
            on ready {
              anykey
            }
            game.after_dialogue_script => {
              game.Boundary_Lock = false
              BoundaryUnlock
              JS.uiShow ("#txtCommandDiv")
            }
          }
          else if (game.itswarmdownhere_visited = true) {
            if (itswarmdownhere.warm_visits = 1) {
              game.active_play_text = NewStringList()
              game.nowhere_intro = NewStringList()
              game.helpstate = 5
              game.shellventory = "4"
              list add (game.nowhere_intro, "> The snailsweeper stops moving!")
              list add (game.nowhere_intro, "You dig.")
              list add (game.nowhere_intro, "And dig.")
              list add (game.nowhere_intro, ". . . . and dig.")
              list add (game.nowhere_intro, "You and Chewbert.")
              list add (game.nowhere_intro, ". . . .")
              list add (game.nowhere_intro, ". . . . Is it bad if you don't want to empty out the trash?")
              list add (game.nowhere_intro, "There's probably a pillow for Boobert somewhere in all this, right?")
              list add (game.nowhere_intro, ". . . .Whatever.")
              list add (game.nowhere_intro, "If you were that considerate, you wouldn't have lost him in the first place. ")
              list add (game.nowhere_intro, ". . . . It's not like he'd even use it. ")
              list add (game.nowhere_intro, "He likes sleeping on your shoulder. ")
              list add (game.nowhere_intro, "Will you stay?")
              list add (game.nowhere_intro, "YES/NO")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykey
                JS.eval ("window.cachedAudio2.play();")
              }
              game.after_dialogue_script => {
                itswarmdownhere.warm_visits = 2
                game.Boundary_Lock = false
                BoundaryUnlock
                JS.uiShow ("#txtCommandDiv")
                get input {
                  if (LCase(result) = "yes") {
                    game.Boundary_Lock = true
                    BoundaryLock
                    JS.uiHide ("#txtCommandDiv")
                    player.care = player.care+1
                  }
                  else {
                    player.care = player.care
                  }
                }
                SetTimeout (60) {
                  if (game.pov.parent = itswarmdownhere) {
                    game.active_play_text = NewStringList()
                    game.nowhere_intro = NewStringList()
                    list add (game.nowhere_intro, "You try not to think about Looie too hard.")
                    list add (game.nowhere_intro, "Either he's not really Looie. . . .")
                    list add (game.nowhere_intro, "Or he's been lost in the dark longer than you have.")
                    list add (game.nowhere_intro, ". . . .")
                    list add (game.nowhere_intro, "You lost him, once. ")
                    list add (game.nowhere_intro, "Your hair could've grown to the floor and back and he was still gone.")
                    list add (game.nowhere_intro, "You thought you found him, though.")
                    list add (game.nowhere_intro, ". . . . ")
                    list add (game.nowhere_intro, "(You settle in for the sounds of silence and unease while the snailsweeper awaits your return to the CONSOLE.)")
                    foreach (item, game.nowhere_intro) {
                      list add (game.active_play_text, item)
                    }
                    on ready {
                      anykey
                    }
                    game.after_dialogue_script => {
                      game.Boundary_Lock = false
                      BoundaryUnlock
                      JS.uiShow ("#txtCommandDiv")
                    }
                  }
                }
              }
            }
            else if (itswarmdownhere.warm_visits = 2) {
              game.active_play_text = NewStringList()
              game.nowhere_intro = NewStringList()
              game.helpstate = 5
              game.shellventory = "4"
              list add (game.nowhere_intro, "> The snailsweeper stops moving!")
              list add (game.nowhere_intro, "You dig.")
              list add (game.nowhere_intro, "You dig deep.")
              list add (game.nowhere_intro, "You dig deeper.")
              list add (game.nowhere_intro, "Loobert Chewbert Boobert doesn't dig.")
              list add (game.nowhere_intro, "He shouldn't have to dig around in the trash like  you do.")
              list add (game.nowhere_intro, ". . . . There's a little hole in his armpit. ")
              list add (game.nowhere_intro, "Has that always been there?")
              list add (game.nowhere_intro, "You press your fingerpad against it. ")
              list add (game.nowhere_intro, ". . . . ")
              list add (game.nowhere_intro, ". . . . ")
              list add (game.nowhere_intro, ". . . Yeah.  ")
              list add (game.nowhere_intro, "Same as always. ")
              list add (game.nowhere_intro, "Will you stay?")
              list add (game.nowhere_intro, "YES/NO")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykey
                JS.eval ("window.cachedAudio2.play();")
              }
              game.after_dialogue_script => {
                itswarmdownhere.warm_visits = 3
                game.Boundary_Lock = false
                BoundaryUnlock
                JS.uiShow ("#txtCommandDiv")
                get input {
                  if (LCase(result) = "yes") {
                    game.Boundary_Lock = true
                    BoundaryLock
                    JS.uiHide ("#txtCommandDiv")
                    player.care = player.care+1
                  }
                  else {
                    player.care = player.care
                  }
                }
                SetTimeout (75) {
                  if (game.pov.parent = itswarmdownhere) {
                    game.active_play_text = NewStringList()
                    game.nowhere_intro = NewStringList()
                    list add (game.nowhere_intro, "It's never cold in the Vale, but you can still be cold.")
                    list add (game.nowhere_intro, "Maybe you should find a blanket to drag down here.")
                    list add (game.nowhere_intro, "Not that you're cold.")
                    list add (game.nowhere_intro, "Are you?")
                    list add (game.nowhere_intro, ". . . .")
                    list add (game.nowhere_intro, "You don't know who you're trying to worry.")
                    list add (game.nowhere_intro, "You could walk into the deep floods and hardly feel it.")
                    list add (game.nowhere_intro, "And Loobert Boobert Chewbert is a pigeon. ")
                    list add (game.nowhere_intro, "Pigeons love the rain.")
                    list add (game.nowhere_intro, "Maybe they also love the cold.")
                    list add (game.nowhere_intro, ". . . .")
                    list add (game.nowhere_intro, "(You settle in for the sound of silence echoing in a mind you've already lost, while the snailsweeper awaits your return to the CONSOLE.)")
                    foreach (item, game.nowhere_intro) {
                      list add (game.active_play_text, item)
                    }
                    on ready {
                      anykey
                    }
                    game.after_dialogue_script => {
                      game.Boundary_Lock = false
                      BoundaryUnlock
                      JS.uiShow ("#txtCommandDiv")
                    }
                  }
                }
              }
            }
            else if (itswarmdownhere.warm_visits = 3) {
              game.active_play_text = NewStringList()
              player.care = player.care+1
              game.nowhere_intro = NewStringList()
              game.helpstate = 5
              list add (game.nowhere_intro, "> The snailsweeper stops moving!")
              list add (game.nowhere_intro, "You dig.")
              list add (game.nowhere_intro, "You dig into that trash.")
              list add (game.nowhere_intro, "You settle.")
              list add (game.nowhere_intro, "This is normal.")
              list add (game.nowhere_intro, "This is you.")
              list add (game.nowhere_intro, "Will you stay?")
              list add (game.nowhere_intro, "YES/NO")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykey
                JS.eval ("window.cachedAudio2.play();")
              }
              game.after_dialogue_script => {
                game.Boundary_Lock = false
                BoundaryUnlock
                JS.uiShow ("#txtCommandDiv")
                get input {
                  if (LCase(result) = "yes") {
                    game.Boundary_Lock = true
                    BoundaryLock
                    JS.uiHide ("#txtCommandDiv")
                  }
                  else {
                    player.care = player.care
                  }
                }
                SetTimeout (120) {
                  if (game.pov.parent = itswarmdownhere) {
                    game.active_play_text = NewStringList()
                    game.nowhere_intro = NewStringList()
                    list add (game.nowhere_intro, "You look at Loobert.")
                    list add (game.nowhere_intro, "You really look at him.")
                    list add (game.nowhere_intro, "You haven't seen him in so long.")
                    list add (game.nowhere_intro, "You try to commit him to memory.")
                    list add (game.nowhere_intro, "His weird round body..")
                    list add (game.nowhere_intro, "His dumb feet.")
                    list add (game.nowhere_intro, "The way his pigeon face feels smooshed against your face.")
                    list add (game.nowhere_intro, "The way he smells.")
                    list add (game.nowhere_intro, "You want to [REMEMBER] him in full detail forever.")
                    list add (game.nowhere_intro, ". . . .")
                    list add (game.nowhere_intro, "(You settle in for the sounds of silence and distant memories, while the snailsweeper awaits your return to the CONSOLE.)")
                    list add (game.nowhere_intro, "(. . . .You feel like, if this was your last trash huddle in the shell for a while, you'd be okay with that.)")
                    foreach (item, game.nowhere_intro) {
                      list add (game.active_play_text, item)
                    }
                    on ready {
                      anykey
                      firsttime {
                        player.curiosity = player.curiosity+5
                        player.connection = player.connection+5
                        player.lcbcuddles = 1
                      }
                      otherwise {
                      }
                    }
                    game.after_dialogue_script => {
                      game.Boundary_Lock = false
                      BoundaryUnlock
                      JS.uiShow ("#txtCommandDiv")
                    }
                  }
                }
              }
            }
          }
        ]]></enter>
        <firstenter type="script"><![CDATA[
          JS.eval ("if (window.cachedAudio1) { window.cachedAudio1.pause(); window.cachedAudio1.currentTime = 0; }")
          game.Boundary_Lock = true
          BoundaryLock
          JS.uiHide ("#txtCommandDiv")
          game.helpstate = 5
          game.active_play_text = NewStringList()
          game.nowhere_intro = NewStringList()
          list add (game.nowhere_intro, "Good job, buddy.")
          list add (game.nowhere_intro, "You’ve fallen into the shell.")
          list add (game.nowhere_intro, "> The snailsweeper stops moving!")
          list add (game.nowhere_intro, "….Right. The driver’s seat is empty.")
          list add (game.nowhere_intro, "You shift yourself around until that stupid manual isn’t jabbing you in the hip. ")
          list add (game.nowhere_intro, ". . . .")
          list add (game.nowhere_intro, "You found something…. plush.")
          list add (game.nowhere_intro, "Loobert Chewbert Boobert?")
          list add (game.nowhere_intro, "The chewiest looiest Bert that ever Booed?")
          list add (game.nowhere_intro, "What are you doing down here?")
          list add (game.nowhere_intro, "You hold onto him. Just so he doesn’t get lost.")
          list add (game.nowhere_intro, "Just for a moment.")
          list add (game.nowhere_intro, ". . . .")
          list add (game.nowhere_intro, "It’s warm in here. ")
          list add (game.nowhere_intro, "You could fit a cot in here, if you emptied out all the trash.")
          list add (game.nowhere_intro, "You could even get a pillow for Loobert Chewbert Boobert.")
          list add (game.nowhere_intro, "It could be perfect.")
          list add (game.nowhere_intro, "Nice and quiet.")
          list add (game.nowhere_intro, "Always nice and quiet.")
          foreach (item, game.nowhere_intro) {
            list add (game.active_play_text, item)
          }
          game.after_dialogue_script => {
            SetTimeout (8) {
              TextFX_Typewriter ("You suppose you should go back to the CONSOLE. . . .", 20)
              JS.eval ("window.cachedAudio2.play();")
              SetTimeout (8) {
                TextFX_Typewriter ("After all, you can come back here whenever you like. . . .", 20)
                SetTimeout (12) {
                  TextFX_Typewriter ("Even still. . . . you sort of just want to stay.", 20)
                  SetTimeout (8) {
                    TextFX_Typewriter ("Will you stay?", 20)
                    SetTimeout (2) {
                      TextFX_Typewriter ("YES/NO", 20)
                      game.Boundary_Lock = false
                      BoundaryUnlock
                      game.itswarmdownhere_visited = true
                      itswarmdownhere.warm_visits = 1
                      JS.uiShow ("#txtCommandDiv")
                      get input {
                        if (LCase(result) = "yes") {
                          game.Boundary_Lock = true
                          BoundaryLock
                          JS.uiHide ("#txtCommandDiv")
                        }
                        else {
                        }
                      }
                    }
                    SetTimeout (45) {
                      if (game.pov.parent = itswarmdownhere) {
                        game.Boundary_Lock = true
                        BoundaryLock
                        JS.uiHide ("#txtCommandDiv")
                        game.active_play_text = NewStringList()
                        game.nowhere_intro = NewStringList()
                        list add (game.nowhere_intro, ". . . . This is a big improvement on the trash pile you were sleeping in earlier.")
                        list add (game.nowhere_intro, "And you have Looie. ")
                        list add (game.nowhere_intro, "You know it's not really him, but still.")
                        list add (game.nowhere_intro, ". . . .")
                        list add (game.nowhere_intro, "Times like this . . . . ")
                        list add (game.nowhere_intro, "Times like this, it's a little like Calliope's listening.")
                        list add (game.nowhere_intro, "It's so warm. . . . ")
                        list add (game.nowhere_intro, "Nice and quiet . . . . ")
                        list add (game.nowhere_intro, "(You settle in for more of the nice and the quiet, while the snailsweeper awaits your return to the CONSOLE when you're ready.)")
                        foreach (item, game.nowhere_intro) {
                          list add (game.active_play_text, item)
                        }
                        on ready {
                          anykey
                        }
                        game.after_dialogue_script => {
                          game.Boundary_Lock = false
                          BoundaryUnlock
                          JS.uiShow ("#txtCommandDiv")
                        }
                      }
                    }
                  }
                }
              }
            }
          }
          game.shellventory = "4"
          on ready {
            anykey
          }
        ]]></firstenter>
        <displayverbs type="stringlist">
          <value>Look at</value>
          <value>Take</value>
          <value>Open</value>
          <value>Close</value>
        </displayverbs>
        <inventoryverbs type="stringlist">
          <value>Look at</value>
          <value>Use</value>
          <value>Drop</value>
          <value>Open</value>
          <value>Close</value>
        </inventoryverbs>
        <object name="Loobert Chewbert Boobert">
          <inherit name="editor_object" />
          <about type="script"><![CDATA[
            msg ("An absolute role model of a pigeon and an expert on friendship and harmony. He taught you everything he knows and it's not his fault you weren't a very good student. <br/><br/>He brings back so many memories. You can't deny how badly you want to [HUG] him.<br/>")
          ]]></about>
          <hug type="script">
            msg ("You wrap him up in your arms like he'd fly away if you didn't.")
          </hug>
          <remember type="script"><![CDATA[
            firsttime {
              game.active_play_text = NewStringList()
              game.nowhere_intro = NewStringList()
              player.connection = player.connection+1
              player.care = player.care+1
              player.rememberverb = true
              list add (game.nowhere_intro, "You remember rubbing the pad of your thumb over his beady litttle pigeon eyes, over and over, polishing away your fingerprints. ")
              list add (game.nowhere_intro, "He always looked so judgmental.")
              list add (game.nowhere_intro, "You wouldn't blame him for that now.")
              list add (game.nowhere_intro, "You were a terror.")
              list add (game.nowhere_intro, "Not everyone should be given leave to open their ugly maw and chatter at their own discretion.")
              list add (game.nowhere_intro, "You could have been a little softer, said Loobert's shiny little eyes.")
              list add (game.nowhere_intro, "But you already knew that. And he knew that you knew.")
              list add (game.nowhere_intro, "But his eyes still said it. Every single time.")
              list add (game.nowhere_intro, "His beak is sewn shut, and you remember how much you always envied him for that.")
              game.after_dialogue_script => {
                Boundary_Lock = False
                BoundaryUnlock
                JS.uiShow ("#txtCommandDiv")
              }
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykey
              }
            }
            otherwise {
              msg ("His beak is sewn shut, and you remember how much you always envied him for that.<br/>")
            }
          ]]></remember>
        </object>
        <command name="SHELLHUG">
          <pattern>HUG THAT TRASH</pattern>
          <scope>itswarmdownhere</scope>
          <script><![CDATA[
            if (game.intro_end) {
              pc_statupdate
              on ready {
                if (player.care>3) {
                  game.active_play_text = NewStringList()
                  game.nowhere_intro = NewStringList()
                  list add (game.nowhere_intro, "You hug that trash.")
                  list add (game.nowhere_intro, "You hug that trash as hard as you can.")
                  list add (game.nowhere_intro, "You hug that trash until it trembles.")
                  list add (game.nowhere_intro, "You hug that trash until your arms hurt.")
                  list add (game.nowhere_intro, "You reach for Loobert.")
                  list add (game.nowhere_intro, "Your hug that trash more gently.")
                  list add (game.nowhere_intro, "It hurts a little less.")
                  list add (game.nowhere_intro, ". . . .")
                  list add (game.nowhere_intro, "You think you might just stay here.")
                  list add (game.nowhere_intro, "Not forever.")
                  list add (game.nowhere_intro, "Just for a moment.")
                  list add (game.nowhere_intro, "Just stay a moment.")
                }
                else if (player.curiosity>5) {
                  game.active_play_text = NewStringList()
                  game.nowhere_intro = NewStringList()
                  list add (game.nowhere_intro, "You hug that trash.")
                  list add (game.nowhere_intro, "You hug that trash as hard as you can.")
                  list add (game.nowhere_intro, "You hug that trash until it trembles.")
                  list add (game.nowhere_intro, "You hug that trash until your arms hurt.")
                  list add (game.nowhere_intro, ". . . .")
                  list add (game.nowhere_intro, "You've never seen this part of Grotto Vale before.")
                  list add (game.nowhere_intro, "You wonder how deep the grove marble foundation is here.")
                  list add (game.nowhere_intro, "You wonder if there's any real snails or mushrooms or anything to break it down, here.")
                  list add (game.nowhere_intro, "You wonder if there's anything alive at all, out here.")
                  list add (game.nowhere_intro, "Maybe trash lasts forever here.")
                  list add (game.nowhere_intro, "Maybe you. . . .")
                  list add (game.nowhere_intro, ". . . .")
                  list add (game.nowhere_intro, "You think you might just stay here.")
                  list add (game.nowhere_intro, "Not here with the forever trash. Just here in the shell.")
                  list add (game.nowhere_intro, "And not forever.")
                  list add (game.nowhere_intro, "Just for a moment.")
                  list add (game.nowhere_intro, "Just stay a moment.")
                }
                else {
                  game.active_play_text = NewStringList()
                  game.nowhere_intro = NewStringList()
                  list add (game.nowhere_intro, "You hug that trash.")
                  list add (game.nowhere_intro, "You hug that trash as hard as you can.")
                  list add (game.nowhere_intro, "You hug that trash until it trembles.")
                  list add (game.nowhere_intro, "You hug that trash until your arms hurt.")
                  list add (game.nowhere_intro, ". . . .")
                  list add (game.nowhere_intro, "You think you might just stay here.")
                  list add (game.nowhere_intro, "Not forever.")
                  list add (game.nowhere_intro, "Just for a moment.")
                  list add (game.nowhere_intro, "Just stay a moment.")
                }
                foreach (item, game.nowhere_intro) {
                  list add (game.active_play_text, item)
                }
                on ready {
                  anykey
                }
                game.after_dialogue_script => {
                  SetTimeout (30) {
                    game.active_play_text = NewStringList()
                    game.nowhere_intro = NewStringList()
                    list add (game.nowhere_intro, ". . . ?")
                    list add (game.nowhere_intro, "There's a leaf of paper here.")
                    list add (game.nowhere_intro, "It's your handwriting.")
                    list add (game.nowhere_intro, "You read it:")
                    foreach (item, game.nowhere_intro) {
                      list add (game.active_play_text, item)
                    }
                    on ready {
                      anykey
                    }
                    game.after_dialogue_script => {
                      game.active_play_text = NewStringList()
                      game.nowhere_intro = NewStringList()
                      list add (game.nowhere_intro, "\"In the world you're from")
                      list add (game.nowhere_intro, "Where you thought you belonged")
                      list add (game.nowhere_intro, "So long ago<br/>")
                      list add (game.nowhere_intro, "In the world you're from")
                      list add (game.nowhere_intro, "You remembered for so long")
                      list add (game.nowhere_intro, "Places other people know")
                      list add (game.nowhere_intro, "Places you're not for")
                      list add (game.nowhere_intro, "Places you can't go\"")
                      foreach (item, game.nowhere_intro) {
                        list add (game.active_play_text, item)
                      }
                      on ready {
                        JS.eval ("window.cachedAudio3.play();")
                        SetFontName ("'Palatino Linotype', 'Book Antiqua', Palatino, serif")
                        SetFontSize (16)
                        intheworld
                      }
                      game.after_dialogue_script => {
                        game.active_play_text = NewStringList()
                        game.nowhere_intro = NewStringList()
                        list add (game.nowhere_intro, ". . . .")
                        list add (game.nowhere_intro, ". . . .")
                        list add (game.nowhere_intro, "You suppose you remember writing that.")
                        list add (game.nowhere_intro, "You suppose you shouldn't be surprised that Calliope's throwing everything in your face again.")
                        list add (game.nowhere_intro, "You suppose. . . . she's always going to find a way to do that.")
                        list add (game.nowhere_intro, "You suppose. . . .")
                        list add (game.nowhere_intro, ". . . .")
                        list add (game.nowhere_intro, ". . . .you shouldn't just hide in the shell forever.")
                        list add (game.nowhere_intro, "You should get back in the driver's seat.")
                        list add (game.nowhere_intro, "You should see for yourself if this thing is real enough to bring you back to somewhere with mornings and moons. ")
                        list add (game.nowhere_intro, "You should even talk to Nap Head, if it comes to that.")
                        list add (game.nowhere_intro, "Visions in the dark, your body is so heavy.")
                        list add (game.nowhere_intro, "All you did was hug some trash and read some words, and you feel all twitchy and hollow.")
                        list add (game.nowhere_intro, "Your bones feel dense and dry as an old book, and just as crinkled.")
                        list add (game.nowhere_intro, "And you know how hard it's going to be to climb back out of here.")
                        list add (game.nowhere_intro, "You know all you're doing is going nowhere, at a snail's pace.")
                        list add (game.nowhere_intro, "You've earned some rest.")
                        list add (game.nowhere_intro, "Will you stay?")
                        list add (game.nowhere_intro, "YES/NO")
                        foreach (item, game.nowhere_intro) {
                          list add (game.active_play_text, item)
                        }
                        on ready {
                          SetWebFontName ("Press Start 2P")
                          SetFontSize (12)
                          anykey
                        }
                        game.after_dialogue_script => {
                          JS.uiShow ("#txtCommandDiv")
                          game.Boundary_Lock = false
                          BoundaryUnlock
                          get input {
                            if (LCase(result) = "yes") {
                              game.Boundary_Lock = true
                              BoundaryLock
                              JS.uiHide ("#txtCommandDiv")
                              game.nowhere_intro = NewStringList()
                              list add (game.nowhere_intro, ". . . .")
                              list add (game.nowhere_intro, "You certainly hope you'll stay a while.")
                              list add (game.nowhere_intro, "You have all your own, personal trash around you.")
                              list add (game.nowhere_intro, "You're held by the shell of a snailsweeper of all things.")
                              list add (game.nowhere_intro, "Real or not.")
                              list add (game.nowhere_intro, "Here, you can be alone.")
                              list add (game.nowhere_intro, "Here, you can be safe.")
                              list add (game.nowhere_intro, "Here, not even the visions can touch you.")
                              list add (game.nowhere_intro, "Why wouldn't you stay?")
                              list add (game.nowhere_intro, "You settle in with Loobert Chewbert Boobert.")
                              list add (game.nowhere_intro, "You settle right into your comfort zone:")
                              list add (game.nowhere_intro, "Right here in your own, personal trash.")
                              list add (game.nowhere_intro, "Right here, in a snailshell full of nobody and nothing.")
                              list add (game.nowhere_intro, "Right here, where you're supposed to be.")
                              list add (game.nowhere_intro, "You close your eyes and ignore the faint smell of onions that curls around you.")
                              list add (game.nowhere_intro, "You try desperately to relax.")
                              list add (game.nowhere_intro, "You keep on going nowhere.")
                              list add (game.nowhere_intro, "After all, the snailsweeper can't go anywhere without its driver.")
                              foreach (item, game.nowhere_intro) {
                                list add (game.active_play_text, item)
                              }
                              game.after_dialogue_script => {
                                introendcredits
                                game.level = "1"
                                player.connection = player.connection-10
                              }
                            }
                            else {
                              game.Boundary_Lock = true
                              BoundaryLock
                              JS.uiHide ("#txtCommandDiv")
                              game.nowhere_intro = NewStringList()
                              list add (game.nowhere_intro, ". . . .")
                              list add (game.nowhere_intro, "Right.")
                              list add (game.nowhere_intro, "Of course not.")
                              list add (game.nowhere_intro, "You're going to get right back out there into the driver's seat.")
                              list add (game.nowhere_intro, "You're going to deal with Nap Head and whatever else drops itself in your way.")
                              list add (game.nowhere_intro, "You're going to shift this snail into run and blaze that slime trail!")
                              list add (game.nowhere_intro, "You're going to do cartwheels of joy in the swimming daylight!")
                              list add (game.nowhere_intro, "Right.")
                              list add (game.nowhere_intro, "Sure you will.")
                              list add (game.nowhere_intro, "Look at you go, digging your way right back out to that console.")
                              list add (game.nowhere_intro, ". . . .")
                              list add (game.nowhere_intro, ". . . .")
                              list add (game.nowhere_intro, "Yeah, that's what you thought.")
                              list add (game.nowhere_intro, ". . . .")
                              list add (game.nowhere_intro, ". . . .you just need a moment.")
                              list add (game.nowhere_intro, "It's not as if the snailsweeper minds.")
                              foreach (item, game.nowhere_intro) {
                                list add (game.active_play_text, item)
                              }
                              game.after_dialogue_script => {
                                introendcredits
                                game.level = "1"
                              }
                            }
                          }
                          on ready {
                            anykey
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          ]]></script>
        </command>
        <command name="SHELLOKAY">
          <pattern>ARE YOU OKAY; ARE YOU OK; r u ok; are you okay?;are you ok?;r u ok?</pattern>
          <scope>itswarminhere</scope>
          <script><![CDATA[
            if (game.intro_ending) {
              SetFontName ("'Lucida Console', Monaco, monospace")
              msg (">"+game.pov.currentcommand)
              pc_statupdate
              on ready {
                if (player.host_lonely < 145 and player.connection > 2 and player.care >3) {
                  game.active_play_text = NewStringList()
                  game.nowhere_intro = NewStringList()
                  list add (game.nowhere_intro, ". . . .")
                  list add (game.nowhere_intro, ". . . .")
                  list add (game.nowhere_intro, "You don't know what you mean by that.")
                  list add (game.nowhere_intro, "You don't know what any of this means.")
                  list add (game.nowhere_intro, "You know so many things.")
                  list add (game.nowhere_intro, "You know how to drive a snailsweeper.")
                  list add (game.nowhere_intro, "You know Nap Head's name.")
                  list add (game.nowhere_intro, "You know how to type on a claviature.")
                  list add (game.nowhere_intro, "You know what trees smell like.")
                  list add (game.nowhere_intro, "You know how to grow onions.")
                  list add (game.nowhere_intro, "You know how to hug trash like you mean it.")
                  list add (game.nowhere_intro, "You hug yourself tight.")
                  list add (game.nowhere_intro, "You try to imagine that you can still smell the trees.")
                  list add (game.nowhere_intro, "You try to imagine that you can see moonlight through your eyelids.")
                  list add (game.nowhere_intro, "You try to imagine that you can hear music on the wind.")
                  list add (game.nowhere_intro, "You try to imagine a place you can go, even if you don't belong there.")
                  list add (game.nowhere_intro, "It doesn't seem to work.")
                  list add (game.nowhere_intro, "This is the most you've seen of anything or nothing in a long while.")
                  list add (game.nowhere_intro, "Your eyes sting.")
                  list add (game.nowhere_intro, "And who knows what Nap Head out there wants from you?")
                  list add (game.nowhere_intro, "The visions never stop.")
                  list add (game.nowhere_intro, "They never leave you alone.")
                  list add (game.nowhere_intro, "That's not true.")
                  list add (game.nowhere_intro, "Sometimes they just abruptly leave you all at once, and that's-")
                  list add (game.nowhere_intro, "That's just so much worse. ")
                  list add (game.nowhere_intro, "You hate that it's worse.")
                  list add (game.nowhere_intro, "You hate that you need visions to keep you company.")
                  list add (game.nowhere_intro, "After all, isn't it for the best?")
                  list add (game.nowhere_intro, "Visions don't care if you're like this.")
                  list add (game.nowhere_intro, "Nap Head certainly doesn't care.")
                  list add (game.nowhere_intro, "You don't. . . .")
                  list add (game.nowhere_intro, "Well.")
                  list add (game.nowhere_intro, "There's not a lot you care about these days, is there?")
                  list add (game.nowhere_intro, "You're just. . . . like this.")
                  list add (game.nowhere_intro, "You're just. . . . ")
                  list add (game.nowhere_intro, "Going to stay down here with Looie for a few more minutes.")
                  list add (game.nowhere_intro, "Just. . . . stay a few minutes.")
                }
                else if (player.host_lonely <145 and player.connection >2) {
                  game.active_play_text = NewStringList()
                  game.nowhere_intro = NewStringList()
                  list add (game.nowhere_intro, "What kind of a question is that?")
                  list add (game.nowhere_intro, "Why would you even - ")
                  list add (game.nowhere_intro, "You already know exactly how - ")
                  list add (game.nowhere_intro, "You -")
                  list add (game.nowhere_intro, "- !!")
                  list add (game.nowhere_intro, ". . . .")
                  list add (game.nowhere_intro, "You hug yourself tight.")
                  list add (game.nowhere_intro, "You close your eyes hard.")
                  list add (game.nowhere_intro, "You try to imagine that you can still smell the trees.")
                  list add (game.nowhere_intro, "You try to imagine that you can see moonlight through your eyelids.")
                  list add (game.nowhere_intro, "You try to imagine that you can hear music on the wind.")
                  list add (game.nowhere_intro, "You try to imagine a place you can go, even if you don't belong there.")
                  list add (game.nowhere_intro, "It doesn't seem to work.")
                  list add (game.nowhere_intro, "This is the most you've seen of anything or nothing in a long while.")
                  list add (game.nowhere_intro, "The console, the clavi, all this reading?")
                  list add (game.nowhere_intro, "And who knows what Nap Head out there wants from you.")
                  list add (game.nowhere_intro, "The visions never stop.")
                  list add (game.nowhere_intro, "They never leave you alone.")
                  list add (game.nowhere_intro, "Except when they do, and that's - ")
                  list add (game.nowhere_intro, "That's - ")
                  list add (game.nowhere_intro, "That's just so much worse. ")
                  list add (game.nowhere_intro, "You hate that it's worse.")
                  list add (game.nowhere_intro, "You hate that you need visions to keep you company.")
                  list add (game.nowhere_intro, "After all, isn't that for the best?")
                  list add (game.nowhere_intro, "Visions don't care if you're like this.")
                  list add (game.nowhere_intro, "Nap Head certainly doesn't care.")
                  list add (game.nowhere_intro, "And there's no way around it.")
                  list add (game.nowhere_intro, "You are. . . . like this.")
                  list add (game.nowhere_intro, "You're just. . . . ")
                  list add (game.nowhere_intro, "Going to stay down here with Looie for a few more minutes.")
                  list add (game.nowhere_intro, "Just. . . . stay a few minutes.")
                }
                else {
                  game.active_play_text = NewStringList()
                  game.nowhere_intro = NewStringList()
                  list add (game.nowhere_intro, "What kind of a question is that?")
                  list add (game.nowhere_intro, "Why would you even - ")
                  list add (game.nowhere_intro, "You already know exactly how - ")
                  list add (game.nowhere_intro, "You -")
                  list add (game.nowhere_intro, "- !!")
                  list add (game.nowhere_intro, ". . . .")
                  list add (game.nowhere_intro, "You hug yourself tight.")
                  list add (game.nowhere_intro, "This is the most you've seen of anything or nothing in a long while.")
                  list add (game.nowhere_intro, "The console, the clavi, all this reading?")
                  list add (game.nowhere_intro, "And who knows what Nap Head out there wants from you.")
                  list add (game.nowhere_intro, "The visions never stop.")
                  list add (game.nowhere_intro, "They never leave you alone.")
                  list add (game.nowhere_intro, "Except when they do, and that's - ")
                  list add (game.nowhere_intro, "That's - ")
                  list add (game.nowhere_intro, "There's no way around it.")
                  list add (game.nowhere_intro, "You're just like this.")
                  list add (game.nowhere_intro, "You're just. . . . ")
                  list add (game.nowhere_intro, "Going to stay down here with Looie for a few more minutes.")
                  list add (game.nowhere_intro, "Just. . . . stay a few minutes.")
                }
                foreach (item, game.nowhere_intro) {
                  list add (game.active_play_text, item)
                }
                on ready {
                  wait {
                    SetWebFontName ("Press Start 2P")
                    anykey
                  }
                }
                game.after_dialogue_script => {
                  SetTimeout (30) {
                    game.active_play_text = NewStringList()
                    game.nowhere_intro = NewStringList()
                    list add (game.nowhere_intro, ". . . ?")
                    list add (game.nowhere_intro, "There's a leaf of paper here.")
                    list add (game.nowhere_intro, "It's your handwriting.")
                    list add (game.nowhere_intro, "You read it:")
                    foreach (item, game.nowhere_intro) {
                      list add (game.active_play_text, item)
                    }
                    on ready {
                      anykey
                    }
                    game.after_dialogue_script => {
                      game.active_play_text = NewStringList()
                      game.nowhere_intro = NewStringList()
                      list add (game.nowhere_intro, " ")
                      list add (game.nowhere_intro, "\"In the world you're from")
                      list add (game.nowhere_intro, "Where you thought you belonged")
                      list add (game.nowhere_intro, "So long ago<br/>")
                      list add (game.nowhere_intro, "In the world you're from")
                      list add (game.nowhere_intro, "You remembered for so long")
                      list add (game.nowhere_intro, "Places other people know")
                      list add (game.nowhere_intro, "Places you're not for")
                      list add (game.nowhere_intro, "Places you can't go\"")
                      foreach (item, game.nowhere_intro) {
                        list add (game.active_play_text, item)
                      }
                      on ready {
                        JS.eval ("window.cachedAudio3.play();")
                        SetFontName ("'Palatino Linotype', 'Book Antiqua', Palatino, serif")
                        SetFontSize (16)
                        intheworld
                      }
                      game.after_dialogue_script => {
                        game.active_play_text = NewStringList()
                        game.nowhere_intro = NewStringList()
                        list add (game.nowhere_intro, ". . . .")
                        list add (game.nowhere_intro, ". . . .")
                        list add (game.nowhere_intro, "You suppose you remember writing that.")
                        list add (game.nowhere_intro, "You suppose you shouldn't be surprised that Calliope's throwing everything in your face again.")
                        list add (game.nowhere_intro, "You suppose. . . . she's always going to find a way to do that.")
                        list add (game.nowhere_intro, "You suppose. . . .")
                        list add (game.nowhere_intro, ". . . .")
                        list add (game.nowhere_intro, ". . . .you shouldn't just hide in the shell forever.")
                        list add (game.nowhere_intro, "You should get back in the driver's seat.")
                        list add (game.nowhere_intro, "You should see for yourself if this thing is real enough to bring you back to somewhere with mornings and moons. ")
                        list add (game.nowhere_intro, "You should even talk to Nap Head, if it comes to that.")
                        list add (game.nowhere_intro, "Visions in the dark, your body is so heavy.")
                        list add (game.nowhere_intro, "All you did was hug some trash and read some words, and you feel all twitchy and hollow.")
                        list add (game.nowhere_intro, "Your bones feel dense and dry as an old book, and just as crinkled.")
                        list add (game.nowhere_intro, "And you know how hard it's going to be to climb back out of here.")
                        list add (game.nowhere_intro, "You know all you're doing is going nowhere, at a snail's pace.")
                        list add (game.nowhere_intro, "You've earned some rest.")
                        list add (game.nowhere_intro, "Will you stay?")
                        list add (game.nowhere_intro, "YES/NO")
                        foreach (item, game.nowhere_intro) {
                          list add (game.active_play_text, item)
                        }
                        on ready {
                          SetWebFontName ("Press Start 2P")
                          SetFontSize (12)
                          anykey
                        }
                        game.after_dialogue_script => {
                          JS.uiShow ("#txtCommandDiv")
                          game.Boundary_Lock = false
                          BoundaryUnlock
                          get input {
                            if (LCase(result) = "yes") {
                              game.Boundary_Lock = true
                              BoundaryLock
                              JS.uiHide ("#txtCommandDiv")
                              game.nowhere_intro = NewStringList()
                              list add (game.nowhere_intro, ". . . .")
                              list add (game.nowhere_intro, "You certainly hope you'll stay a while.")
                              list add (game.nowhere_intro, "You have all your own, personal trash around you.")
                              list add (game.nowhere_intro, "You're held by the shell of a snailsweeper of all things.")
                              list add (game.nowhere_intro, "Real or not.")
                              list add (game.nowhere_intro, "Here, you can be alone.")
                              list add (game.nowhere_intro, "Here, you can be safe.")
                              list add (game.nowhere_intro, "Here, not even the visions can touch you.")
                              list add (game.nowhere_intro, "Why wouldn't you stay?")
                              list add (game.nowhere_intro, "You settle in with Loobert Chewbert Boobert.")
                              list add (game.nowhere_intro, "You settle right into your comfort zone:")
                              list add (game.nowhere_intro, "Right here in your own, personal trash.")
                              list add (game.nowhere_intro, "Right here, in a snailshell full of nobody and nothing.")
                              list add (game.nowhere_intro, "Right here, where you're supposed to be.")
                              list add (game.nowhere_intro, "You close your eyes and ignore the faint smell of onions that curls around you.")
                              list add (game.nowhere_intro, "You try desperately to relax.")
                              list add (game.nowhere_intro, "You keep on going nowhere.")
                              list add (game.nowhere_intro, "After all, the snailsweeper can't go anywhere without its driver.")
                              foreach (item, game.nowhere_intro) {
                                list add (game.active_play_text, item)
                              }
                              game.after_dialogue_script => {
                                introendcredits
                                game.level = "1"
                                player.connection = player.connection-10
                              }
                            }
                            else {
                              game.Boundary_Lock = true
                              BoundaryLock
                              JS.uiHide ("#txtCommandDiv")
                              game.nowhere_intro = NewStringList()
                              list add (game.nowhere_intro, ". . . .")
                              list add (game.nowhere_intro, "Right.")
                              list add (game.nowhere_intro, "Of course not.")
                              list add (game.nowhere_intro, "You're going to get right back out there into the driver's seat.")
                              list add (game.nowhere_intro, "You're going to deal with Nap Head and whatever else drops itself in your way.")
                              list add (game.nowhere_intro, "You're going to shift this snail into run and blaze that slime trail!")
                              list add (game.nowhere_intro, "You're going to do cartwheels of joy in the swimming daylight!")
                              list add (game.nowhere_intro, "Right.")
                              list add (game.nowhere_intro, "Sure you will.")
                              list add (game.nowhere_intro, "Look at you go, digging your way right back out to that console.")
                              list add (game.nowhere_intro, ". . . .")
                              list add (game.nowhere_intro, ". . . .")
                              list add (game.nowhere_intro, "Yeah, that's what you thought.")
                              list add (game.nowhere_intro, ". . . .")
                              list add (game.nowhere_intro, ". . . .you just need a moment.")
                              list add (game.nowhere_intro, "It's not as if the snailsweeper minds.")
                              foreach (item, game.nowhere_intro) {
                                list add (game.active_play_text, item)
                              }
                              game.after_dialogue_script => {
                                introendcredits
                                game.level = "1"
                              }
                            }
                          }
                          on ready {
                            anykey
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          ]]></script>
        </command>
      </object>
      <command name="Shell">
        <pattern>Shell</pattern>
        <scope>Snailsweeper</scope>
        <script><![CDATA[
          if (game.pov.parent = itswarmdownhere) {
            msg ("You're already in the shell. When you're ready to come out, you have to reach toward the CONSOLE.")
          }
          else if (game.pov.parent = Snailsweeper) {
            DisableTurnScript (DriverSeat)
            if (game.admintools and game.shellventory="4" and game.pages="1" and not game.introcomplete) {
              game.inendconsoletrigger = true
              game.introcomplete = true
              JS.eval ("if (window.cachedAudio7) { window.cachedAudio7.pause(); window.cachedAudio7.currentTime = 0; }")
            }
            if (game.shellventory="4") {
              HelperOpenObject (Shlvl One)
              MoveObject (Snailsweeper Operation Manual, Shlvl One)
              MoveObject (Latest Pages, Shlvl One)
              MoveObject (Pen Set, Shlvl One)
              MoveObject (Hat with no eyes, Shlvl One)
              MoveObject (Loobert Chewbert Boobert, Shlvl One)
              game.helpstate = 2
              game.nowhere_intro = null
              game.active_play_text = null
              game.nowhere_intro = NewStringList()
              game.active_play_text = NewStringList()
              list add (game.nowhere_intro, "You reach yourself into the shell hole.")
              list add (game.nowhere_intro, "You grope around and find a few things:")
              list add (game.nowhere_intro, "[Fuzzy ball of PRESERVATIVE] <br/>[Tube of INSPIRATION]<br/>[Official Grull & Trawl Snailsweeper Operation MANUAL] <br/>[Latest PAGES] <br/>[PEN and well] <br/>[HAT without eyes] <br/>[LOOBERT CHEWBERT BOOBERT]<br/>")
              list add (game.nowhere_intro, "You can DIG in the trash if you want, and you can go back to the CONSOLE when you're done.")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykey
              }
              game.after_dialogue_script => {
                game.Boundary_Lock = false
                BoundaryUnlock
                JS.uiShow ("#txtCommandDiv")
              }
            }
            else if (game.shellventory="2") {
              HelperOpenObject (Shlvl One)
              game.helpstate = 3
              game.nowhere_intro = null
              game.active_play_text = null
              game.nowhere_intro = NewStringList()
              game.active_play_text = NewStringList()
              list add (game.nowhere_intro, "You turn around.")
              list add (game.nowhere_intro, "You move the back cushion.")
              list add (game.nowhere_intro, "You reach your arm inside the hole.")
              list add (game.nowhere_intro, "You reach your face inside the hole.")
              list add (game.nowhere_intro, "You reach your ear inside the hole.")
              list add (game.nowhere_intro, "There sure is a whole lot of trash back here.")
              list add (game.nowhere_intro, "Some of it is even important to you:")
              list add (game.nowhere_intro, "[Fuzzy ball of PRESERVATIVE].<br/>[Tube of INSPIRATION]<br/>[Latest PAGES]<br/>[Snailsweeper MANUAL]")
              list add (game.nowhere_intro, "You can dig DEEP to find more, or you can go back to the CONSOLE.")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykey
                game.shlvl_two = true
              }
              game.after_dialogue_script => {
                game.Boundary_Lock = false
                BoundaryUnlock
                JS.uiShow ("#txtCommandDiv")
              }
            }
            else if (game.shellventory="3") {
              HelperOpenObject (Shlvl One)
              game.helpstate = 3
              game.nowhere_intro = null
              game.active_play_text = null
              game.nowhere_intro = NewStringList()
              game.active_play_text = NewStringList()
              list add (game.nowhere_intro, "You turn around.")
              list add (game.nowhere_intro, "You move the back cushion.")
              list add (game.nowhere_intro, "You reach your arm inside the hole.")
              list add (game.nowhere_intro, "You reach your face inside the hole.")
              list add (game.nowhere_intro, "You reach your ear inside the hole.")
              list add (game.nowhere_intro, "There sure is a whole lot of trash back here.")
              list add (game.nowhere_intro, "Some of it is even important to you:")
              list add (game.nowhere_intro, "[Fuzzy ball of PRESERVATIVE].<br/>[Tube of INSPIRATION]<br/>[Latest PAGES]<br/>[Snailsweeper MANUAL] <br/>[PEN and well] <br/>[HAT without eyes]")
              list add (game.nowhere_intro, "You can dig DEEPER to find more, or you can go back to the CONSOLE.")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykey
                game.shlvl_two = true
              }
              game.after_dialogue_script => {
                game.Boundary_Lock = false
                BoundaryUnlock
                JS.uiShow ("#txtCommandDiv")
              }
            }
            else {
              on ready {
                HelperOpenObject (Shlvl One)
                game.helpstate = 2
                game.nowhere_intro = null
                game.active_play_text = null
                game.active_play_text = NewStringList()
                game.nowhere_intro = NewStringList()
                list add (game.nowhere_intro, "You turn around.")
                list add (game.nowhere_intro, "You move the back cushion.")
                list add (game.nowhere_intro, "You reach your arm inside the hole.")
                list add (game.nowhere_intro, "You reach your face inside the hole.")
                list add (game.nowhere_intro, "You reach your ear inside the hole.")
                list add (game.nowhere_intro, "There sure is a whole lot of trash back here.")
                list add (game.nowhere_intro, "Some of it is even important to you:")
                list add (game.nowhere_intro, "[Fuzzy ball of PRESERVATIVE].<br/>[Tube of INSPIRATION]")
                list add (game.nowhere_intro, "You can DIG to find more, or you can go back to the CONSOLE.")
                foreach (item, game.nowhere_intro) {
                  list add (game.active_play_text, item)
                }
                on ready {
                  anykey
                }
                game.after_dialogue_script => {
                  game.Boundary_Lock = false
                  BoundaryUnlock
                  JS.uiShow ("#txtCommandDiv")
                }
              }
            }
          }
        ]]></script>
      </command>
      <command name="Shell Dig">
        <pattern>Dig</pattern>
        <scope>Snailsweeper</scope>
        <script><![CDATA[
          if (game.pov.parent = Snailsweeper) {
            if (game.shellventory = "4") {
              MoveObject (player, itswarmdownhere)
            }
            else if (game.shellventory="2" or game.shellventory="3") {
              msg (" ")
            }
            else {
              HelperOpenObject (Shlvl Two)
              game.helpstate = 3
              game.shellventory = "2"
              game.shlvl_two = true
              game.active_play_text = NewStringList()
              game.nowhere_intro = NewStringList()
              list add (game.nowhere_intro, "You dig around in the trash.")
              list add (game.nowhere_intro, "You find something interesting:")
              list add (game.nowhere_intro, "[Latest PAGES]<br/>[Snailsweeper MANUAL]")
              list add (game.nowhere_intro, "It's been so long since you had enough light to [READ] anything. . . . ")
              list add (game.nowhere_intro, "If you dig DEEP you might find more. Or you can go back to the CONSOLE.")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykey
              }
              game.after_dialogue_script => {
                game.Boundary_Lock = false
                BoundaryUnlock
                JS.uiShow ("#txtCommandDiv")
              }
            }
          }
          else if (game.pov.parent = itswarmdownhere) {
            msg (" ")
          }
          else {
          }
        ]]></script>
      </command>
      <command name="Shell Dig Deep">
        <pattern>Deep</pattern>
        <scope type="string"></scope>
        <script><![CDATA[
          if (game.pov.parent = Snailsweeper) {
            if (game.shellventory = "4") {
            }
            else {
              HelperOpenObject (Shlvl Three)
              game.helpstate = 4
              game.shlvl_two = false
              game.shlvl_three = true
              game.shellventory = "3"
              game.active_play_text = NewStringList()
              game.nowhere_intro = NewStringList()
              list add (game.nowhere_intro, "You dig deep.")
              list add (game.nowhere_intro, "You are reverse-hip-deep in trash now.")
              list add (game.nowhere_intro, "This isn't what you wanted, but it's not like anyone else is going to dig around in your trash.")
              list add (game.nowhere_intro, "Your hands find something:")
              list add (game.nowhere_intro, "[PEN and well] <br/>[HAT without eyes]")
              list add (game.nowhere_intro, "You're not sure what you even need these for. You can dig DEEPER, if you want.")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykey
              }
              game.after_dialogue_script => {
                game.Boundary_Lock = false
                BoundaryUnlock
                JS.uiShow ("#txtCommandDiv")
              }
            }
          }
          else if (game.pov.parent = itswarmdownhere) {
            msg (" ")
          }
        ]]></script>
      </command>
      <command name="Shell Dig Deeper">
        <pattern>Deeper</pattern>
        <script>
          if (game.pov.parent = itswarmdownhere) {
            msg (" ")
          }
          else if (game.pov.parent = Snailsweeper) {
            if (game.shellventory = "4") {
            }
            else if (game.pov.parent = itswarmdownhere) {
              msg (" ")
            }
            else {
              game.shlvl_two = false
              game.shlvl_three = true
              game.shellventory = "3"
              on ready {
                MoveObject (player, itswarmdownhere)
              }
            }
          }
        </script>
      </command>
      <command name="Console">
        <pattern>Console</pattern>
        <scope type="string"></scope>
        <script><![CDATA[
          if (game.pov.parent = Snailsweeper) {
            if (game.inendconsoletrigger) {
              ConsoleIntroEnd
            }
            else if (game.admintools and game.shellventory="4" and game.pages="1" and not game.introcomplete and not player.wantskettle) {
              game.inendconsoletrigger = true
              game.introcomplete = true
              msg ("You see the [MAGIC LIGHT], the [RUN LEVER], the [TILT SHIFT], the [STEERING VALVES], the [NAV POINTER], the [COLOR WHEEL], the [CLAVIATURE].<br/> <br/>Most of it looks powered down, but you can still learn more [ABOUT] them.")
              EnableTurnScript (DriverSeat)
            }
            else if (game.admintools and game.shellventory="4" and game.pages="1" and player.wantskettle and not game.introcomplete) {
              game.inendconsoletrigger = true
              game.introcomplete = true
              msg ("You see the [MAGIC LIGHT], the [RUN LEVER], the [TILT SHIFT], the [Steering VALVES], the [NAV POINTER], the [COLOR WHEEL], the [CLAVIature], and the [KETTLE].<br/> <br/>Most of it looks powered down, but you can still learn more [ABOUT] them.")
              EnableTurnScript (DriverSeat)
            }
            else if (player.wantskettle) {
              HelperCloseObject (Shlvl Three)
              HelperCloseObject (Shlvl Two)
              HelperCloseObject (Shlvl One)
              msg ("You see the [MAGIC LIGHT], the [RUN LEVER], the [TILT SHIFT], the [Steering VALVES], the [NAV POINTER], the [COLOR WHEEL], the [CLAVIature], and the [KETTLE].<br/> <br/>Most of it looks powered down, but you can still learn more [ABOUT] them.")
              MakeObjectVisible (Kettle)
              EnableTurnScript (DriverSeat)
            }
            else {
              HelperCloseObject (Shlvl Three)
              HelperCloseObject (Shlvl Two)
              HelperCloseObject (Shlvl One)
              msg ("You see the [MAGIC LIGHT], the [RUN LEVER], the [TILT SHIFT], the [STEERING VALVES], the [NAV POINTER], the [COLOR WHEEL], the [CLAVIATURE].<br/> <br/>Most of it looks powered down, but you can still learn more [ABOUT] them.")
              EnableTurnScript (DriverSeat)
            }
            if (game.admintools and game.shellventory="4" and game.pages="1") {
              game.helpstate = 7
            }
            else if (game.admintoolsstart) {
              game.helpstate = 6
            }
            else {
              game.helpstate = 1
            }
          }
          else if (game.pov.parent = itswarmdownhere) {
            if (game.intro_ending) {
              TextFX_Typewriter (". . . . Not yet.", 20)
            }
            else if (not game.intro_ending) {
              UpToConsole (4)
            }
          }
          else {
            if (game.shlvl_three) {
              UpToConsole (3)
            }
            else if (game.shlvl_two) {
              UpToConsole (2)
            }
            else if (game.shlvl_one and not game.shlvl_two) {
              UpToConsole (1)
            }
          }
        ]]></script>
      </command>
      <command name="GET OUT">
        <pattern>GET OUT</pattern>
        <script><![CDATA[
          if (game.getoutlock) {
            msg ("You don't want to do that right now.")
          }
          else {
            if (Contains (Snailsweeper,player)) {
              MoveObject (player, Snailsweeper.parent)
              msg ("> You get out of the snailsweeper!")
            }
            else {
              msg ("> You are already out of the snailsweeper.")
            }
          }
        ]]></script>
      </command>
      <command name="Promise">
        <pattern>Promise</pattern>
        <scope>snailsweeper</scope>
        <script><![CDATA[
          if (game.admintoolsstart and not game.admintoolsstart2) {
            msg ("Please provide your Grull & Trawl Identification Number")
            on ready {
              game.admintoolsstart2 = true
            }
          }
          else {
          }
        ]]></script>
      </command>
      <command name="GT Ident">
        <pattern>248</pattern>
        <scope>snailsweeper</scope>
        <script><![CDATA[
          if (game.admintoolsstart2 and not Key.admintools) {
            msg ("You agree not to feel alone. <br/><br/>YES/NO<br/>")
            get input {
              if (LCase(result) = "yes") {
                game.admintools = true
                game.admintoolsstart = false
                game.admintoolsstart2 = false
                set (Key, "admintools", true)
                set (Snailsweeper Operation Manual, "admintools", true)
                JS.eval ("$('body').css('background-image', 'url(\"" + GetFileURL("calliopemarginwatching3.png") + "\")');")
                SetTimeout (1) {
                  JS.eval ("$('body').css('background-image', 'url(\"" + GetFileURL("calliopemarginnormal3.png") + "\")');")
                }
                SetForegroundColour ("White")
                player.connection = player.connection+1
                msg ("Administrator Detected!")
                msg ("Welcome to Safe Mode!")
                TextFX_Typewriter ("You feel the key get agitated, almost like it wants to go back to the SHELL to check the manual.", 20)
              }
              else if (LCase(result) <> "yes") {
                msg ("Safe Mode Initiation Canceled.")
                set (Key, "admintools", true)
                EnableTurnScript (Ping Kill)
              }
            }
          }
          else if (game.admintoolsstart2 and Key.admintools) {
            msg ("No Token Found.")
          }
          else {
          }
        ]]></script>
      </command>
      <object name="Curtains">
        <inherit name="editor_object" />
        <about>Helpful when you or the world around you need some privacy.</about>
        <raise type="script"><![CDATA[
          if (game.intro_end) {
            if (game.pov.parent = Snailsweeper) {
              game.active_play_text = NewStringList()
              game.nowhere_intro = NewStringList()
              list add (game.nowhere_intro, "You find the drawstring and raise the curtains. ")
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykey
              }
              game.after_dialogue_script => {
                img_url = "https://i.imgur.com/f7pKuRe.gif"
                JS.eval ("var newDiv = $('<div style=\"text-align:center; margin:10px 0;\"></div>'); var img = $('<img src=\"" + img_url + "\" style=\"display:block; margin:0 auto; max-width:100%; max-height:300px;\" />'); newDiv.append(img); var last = $('#divOutput div').last(); if (last.length) { last.after(newDiv); } else { $('#divOutput').append(newDiv); } setTimeout(function() { $('#divOutput').scrollTop($('#divOutput')[0].scrollHeight); }, 50);")
                SetTimeout (3) {
                  JS.eval ("window.cachedAudio6.play();")
                }
                SetTimeout (20) {
                  game.active_play_text = NewStringList()
                  game.nowhere_intro = NewStringList()
                  list add (game.nowhere_intro, "Oh.")
                  list add (game.nowhere_intro, "The trees really are gone.")
                  list add (game.nowhere_intro, "You know the light itself is a vision, so all of this is suspect, but . . . .")
                  list add (game.nowhere_intro, ". . . .it's been so long since you actually saw any of Grotto Vale.")
                  list add (game.nowhere_intro, "So even if it's a small, dirty part of Grotto Vale that nobody wants to see. . . . ")
                  list add (game.nowhere_intro, "A place that doesn't really count. . . . ")
                  list add (game.nowhere_intro, ". . . .because it probably isn't real. . . . ")
                  list add (game.nowhere_intro, ". . . .and it wouldn't matter if it was. . . . ")
                  list add (game.nowhere_intro, ". . . .You don't mind seeing it. ")
                  list add (game.nowhere_intro, ". . . .")
                  list add (game.nowhere_intro, ". . . .")
                  list add (game.nowhere_intro, "You wonder what Nap Head wants from you.")
                  list add (game.nowhere_intro, "You suppose that doesn't matter, either.")
                  list add (game.nowhere_intro, ". . . .")
                  list add (game.nowhere_intro, ". . . .")
                  list add (game.nowhere_intro, ". . . .You think you'd very much like to go back inside the SHELL.")
                  foreach (item, game.nowhere_intro) {
                    list add (game.active_play_text, item)
                  }
                  on ready {
                    anykey
                  }
                  game.after_dialogue_script => {
                    game.Boundary_Lock = false
                    BoundaryUnlock
                    JS.uiShow ("#txtCommandDiv")
                  }
                }
              }
              game.intro_ending = true
            }
            else if (game.pov.parent = itswarmdownhere) {
              msg ("You definitely can't  reach that from in here. You have to get back to the CONSOLE.")
            }
          }
          else if (game.pov.parent = Snailsweeper) {
            msg ("You can still hear the trees.<br/>")
          }
        ]]></raise>
      </object>
      <object name="Kettle">
        <inherit name="editor_object" />
        <visible type="boolean">false</visible>
        <drunk type="boolean">false</drunk>
        <about type="script"><![CDATA[
          firsttime {
            msg (". . . . Did you somehow completely miss this earlier?<br/><br/>There isn't enough magic to power it, but maybe you could still have a [DRINK].<br/>")
          }
          otherwise {
            if (Kettle.drunk = true) {
              msg ("The water inside is lukewarm and a little salty.<br/>")
            }
            else {
              msg ("A hot drink sounds nice right now. Too bad.<br/>")
            }
          }
        ]]></about>
        <drink type="script"><![CDATA[
          firsttime {
            msg ("You eagerly make a gap in your scarves to tip the spout into.<br/><br/>You drink.<br/>")
            player.care = player.care+1
            set (Kettle, "drunk", true)
          }
          otherwise {
            msg ("You're not thirsty enough to go through that again.<br/>")
          }
        ]]></drink>
      </object>
      <turnscript name="DriverSeat">
        <enabled />
        <script>
          if (game.pov.parent = Snailsweeper) {
            if (Snailsweeper.driverseat = 30) {
              driverseat
            }
            else {
              set (Snailsweeper, "driverseat", Snailsweeper.driverseat+1)
            }
          }
        </script>
      </turnscript>
    </object>
    <turnscript name="Intro Counter Snailsweeper">
      <script><![CDATA[
        if (game.move_counter  = 6) {
          JS.uiHide ("#txtCommandDiv")
          game.active_play_text = NewStringList()
          game.nowhere_intro = NewStringList()
          list add (game.nowhere_intro, "You hear the sound of tree branches brushing past the outside of the SHELL.")
          list add (game.nowhere_intro, "You should really get things organized in there. . . .")
          list add (game.nowhere_intro, "When you're ready, it's time to check out the SHELL.")
          game.move_counter = 0
          foreach (item, game.nowhere_intro) {
            list add (game.active_play_text, item)
          }
          on ready {
            anykey
          }
          game.after_dialogue_script => {
            on ready {
              DisableTurnScript (Intro Counter Snailsweeper)
            }
            game.Boundary_Lock = false
            BoundaryUnlock
            JS.uiShow ("#txtCommandDiv")
          }
        }
      ]]></script>
    </turnscript>
    <command name="HUG THAT TRASH">
      <pattern>HUG THAT TRASH</pattern>
      <scope>nowhere</scope>
      <script><![CDATA[
        game.Boundary_Lock = true
        BoundaryLock
        JS.uiHide ("#txtCommandDiv")
        if (nowhere.hugtrash = "0") {
          nowhere.hugtrash = "1"
          msg ("You scoop up as much trash as you can to your chest and belly and face.")
          SetTimeout (1) {
            msg ("Just like that. Again.")
            on ready {
              JS.uiShow ("#txtCommandDiv")
            }
          }
        }
        else if (nowhere.hugtrash = "1") {
          nowhere.hugtrash = "2"
          msg ("You feel all the hard and soft edges in your arms.")
          SetTimeout (1) {
            msg ("Again.")
            on ready {
              JS.uiShow ("#txtCommandDiv")
            }
          }
        }
        else if (nowhere.hugtrash = "2") {
          msg ("You breathe through your scarf and smell only trash.")
          SetTimeout (1) {
            msg ("Again. Like you mean it.")
            nowhere.hugtrash = "3"
            on ready {
              JS.uiShow ("#txtCommandDiv")
            }
          }
        }
        else if (nowhere.hugtrash = "3") {
          msg ("You press your face into it.")
          SetTimeout (1) {
            msg ("One more time.")
            nowhere.hugtrash = "4"
            on ready {
              JS.uiShow ("#txtCommandDiv")
            }
          }
        }
        else if (nowhere.hugtrash  = "4") {
          game.nowhere_intro = NewStringList()
          game.active_play_text = NewStringList()
          player.connection = player.connection+1
          list add (game.nowhere_intro, "It all goes into the snailshell.")
          list add (game.nowhere_intro, "You did it.")
          list add (game.nowhere_intro, "You step toward the snailsweeper, and - ")
          list add (game.nowhere_intro, "You feel a little crunch under your foot.")
          list add (game.nowhere_intro, "Oh no. ")
          list add (game.nowhere_intro, "You fall to your knees.")
          list add (game.nowhere_intro, "You reach down.")
          list add (game.nowhere_intro, "You find a big piece.")
          list add (game.nowhere_intro, "Oh no no no no. ")
          list add (game.nowhere_intro, "You find another piece.")
          list add (game.nowhere_intro, "You find more.")
          list add (game.nowhere_intro, "This can’t be happening. ")
          list add (game.nowhere_intro, "In the dim glow of the snailsweeper, you even manage to find all the pieces. ")
          list add (game.nowhere_intro, "Hopefully.")
          list add (game.nowhere_intro, "How could you have done this?")
          list add (game.nowhere_intro, "How could you have been so stupid?")
          list add (game.nowhere_intro, "You’re going to need this!")
          list add (game.nowhere_intro, "Isn’t it just typical of you to break the one thing you actually need out there?")
          list add (game.nowhere_intro, "You're lucky none of this is real. You're lucky none of this matters.")
          list add (game.nowhere_intro, "Typical. You’re always like this. ")
          list add (game.nowhere_intro, "You put the pieces in a deep pocket where they can sit nice and heavy.")
          list add (game.nowhere_intro, "Maybe you can try to fix it later, if any of this ends up mattering.")
          list add (game.nowhere_intro, "You breathe through your scarf. You only smell trash.")
          list add (game.nowhere_intro, "It’s time to GET IN the snailsweeper.")
          foreach (item, game.nowhere_intro) {
            list add (game.active_play_text, item)
          }
          on ready {
            anykey
          }
          game.after_dialogue_script => {
            nowhere.hugtrash = "5"
            game.Boundary_Lock = false
            BoundaryUnlock
            JS.uiShow ("#txtCommandDiv")
            // SetTimeout (30) {
              // if (game.pov.parent = nowhere) {
                // TextFX_Typewriter ("You find yourself hesitating for some reason.", 20)
                // SetTimeout (3) {
                  // TextFX_Typewriter ("Which is kind of stupid after you already hugged all that trash. ", 20)
                  // SetTimeout (3) {
                    // TextFX_Typewriter ("Whatever HELP you're waiting for isn't coming, so just GET IN the SNAILSWEEPER already.", 20)
                    // }
                  // }
                // }
              // }
          }
        }
        else if (nowhere.hugtrash = "5") {
          TextFX_Typewriter ("You can't help but hug a little more trash, even though it isn't yours.", 20)
          // SetTimeout (30) {
            // TextFX_Typewriter ("You find yourself hesitating for some reason.", 20)
            // SetTimeout (3) {
              // TextFX_Typewriter ("Which is kind of stupid after you already hugged all that trash. ", 20)
              // SetTimeout (3) {
                // TextFX_Typewriter ("Whatever HELP you're waiting for isn't coming, so just GET IN the SNAILSWEEPER already.", 20)
                // }
              // }
            // }
        }
        else {
        }
        on ready {
          game.Boundary_Lock = false
          BoundaryUnlock
          JS.uiShow ("#txtCommandDiv")
        }
      ]]></script>
    </command>
    <command name="GET IN">
      <pattern>GET IN</pattern>
      <script><![CDATA[
        if (nowhere.hugtrash = "5") {
          game.active_play_text = NewStringList()
          game.helpstate = 1
          list add (game.active_play_text, "> You get in the snailsweeper!")
          list add (game.active_play_text, "> The snailsweeper slowly starts to move!")
          on ready {
            anykey
            JS.eval ("window.cachedAudio1.loop = true; window.cachedAudio1.play();")
          }
          game.after_dialogue_script => {
            MoveObject (player, Snailsweeper)
          }
        }
      ]]></script>
    </command>
  </object>
  <object name="atrium">
    <inherit name="editor_room" />
    <object name="Row1">
      <inherit name="editor_room" />
      <object name="ULCorner">
        <inherit name="editor_room" />
        <exit alias="east" to="UpCenter">
          <inherit name="eastdirection" />
        </exit>
        <exit alias="south" to="LMiddle">
          <inherit name="southdirection" />
        </exit>
      </object>
      <object name="UpCenter">
        <inherit name="editor_room" />
        <exit alias="west" to="ULCorner">
          <inherit name="westdirection" />
        </exit>
        <exit alias="east" to="URCorner">
          <inherit name="eastdirection" />
        </exit>
        <exit alias="south" to="MidCenter">
          <inherit name="southdirection" />
        </exit>
        <exit alias="north" to="HeadShelf">
          <inherit name="northdirection" />
        </exit>
      </object>
      <object name="URCorner">
        <inherit name="editor_room" />
        <exit alias="west" to="UpCenter">
          <inherit name="westdirection" />
        </exit>
        <exit alias="south" to="RMiddle">
          <inherit name="southdirection" />
        </exit>
        <object name="Stinky Hill">
          <inherit name="editor_object" />
          <visible />
        </object>
      </object>
    </object>
    <object name="Row2">
      <inherit name="editor_room" />
      <object name="LMiddle">
        <inherit name="editor_room" />
        <exit alias="north" to="ULCorner">
          <inherit name="northdirection" />
        </exit>
        <exit alias="south" to="DLCorner">
          <inherit name="southdirection" />
        </exit>
        <exit alias="east" to="MidCenter">
          <inherit name="eastdirection" />
        </exit>
      </object>
      <object name="MidCenter">
        <inherit name="editor_room" />
        <exit alias="north" to="UpCenter">
          <inherit name="northdirection" />
        </exit>
        <exit alias="south" to="DownCenter">
          <inherit name="southdirection" />
        </exit>
        <exit alias="west" to="LMiddle">
          <inherit name="westdirection" />
        </exit>
        <exit alias="east" to="RMiddle">
          <inherit name="eastdirection" />
        </exit>
      </object>
      <object name="RMiddle">
        <inherit name="editor_room" />
        <exit alias="north" to="URCorner">
          <inherit name="northdirection" />
        </exit>
        <exit alias="west" to="MidCenter">
          <inherit name="westdirection" />
        </exit>
        <exit alias="south" to="DRCorner">
          <inherit name="southdirection" />
        </exit>
        <object name="Silvered Hill">
          <inherit name="editor_object" />
        </object>
      </object>
    </object>
    <object name="Row3">
      <inherit name="editor_room" />
      <object name="DLCorner">
        <inherit name="editor_room" />
        <exit alias="north" to="LMiddle">
          <inherit name="northdirection" />
        </exit>
        <exit alias="east" to="DownCenter">
          <inherit name="eastdirection" />
        </exit>
        <object name="Sickly Hill">
          <inherit name="editor_object" />
        </object>
      </object>
      <object name="DownCenter">
        <inherit name="editor_room" />
        <exit alias="north" to="MidCenter">
          <inherit name="northdirection" />
        </exit>
        <exit alias="west" to="DLCorner">
          <inherit name="westdirection" />
        </exit>
        <exit alias="east" to="DRCorner">
          <inherit name="eastdirection" />
        </exit>
        <exit alias="south" to="TouringLane1">
          <inherit name="southdirection" />
        </exit>
      </object>
      <object name="DRCorner">
        <inherit name="editor_room" />
        <exit alias="north" to="RMiddle">
          <inherit name="northdirection" />
        </exit>
        <exit alias="west" to="DownCenter">
          <inherit name="westdirection" />
        </exit>
        <object name="Stingling Hill">
          <inherit name="editor_object" />
        </object>
      </object>
    </object>
    <object name="TouringLane1">
      <inherit name="editor_room" />
      <exit alias="north" to="DownCenter">
        <inherit name="northdirection" />
      </exit>
    </object>
    <object name="HeadShelf">
      <inherit name="editor_room" />
      <exit alias="south" to="UpCenter">
        <inherit name="southdirection" />
      </exit>
    </object>
  </object>
  <object name="altar">
    <inherit name="editor_room" />
    <firstenter type="script">
      game.typing_test = NewStringList()
      altar.asdfglist = NewStringList()
      list add (altar.asdfglist, "a")
      list add (altar.asdfglist, "s")
      list add (altar.asdfglist, "d")
      list add (altar.asdfglist, "f")
      list add (altar.asdfglist, "g")
      altar.asdfg_valid = true
      altar.asdfg_correct = false
      on ready {
        msg ("You are in the Altar.")
      }
    </firstenter>
    <beforeenter type="script">
    </beforeenter>
    <command name="asdfg test">
      <scope>altar</scope>
      <pattern>asdfg test</pattern>
      <script>
        asdfgtest
      </script>
    </command>
    <object name="FaceFace">
      <inherit name="editor_object" />
      <inherit name="femaleplural" />
      <visible type="boolean">false</visible>
      <usedefaultprefix type="boolean">false</usedefaultprefix>
    </object>
  </object>
  <object name="arcade">
    <inherit name="editor_room" />
    <object name="Wizard">
      <inherit name="editor_object" />
      <inherit name="maleplural" />
      <visible type="boolean">false</visible>
      <usedefaultprefix type="boolean">false</usedefaultprefix>
      <gender>they</gender>
      <article>them</article>
      <possessive>their</possessive>
    </object>
    <object name="maybesomewhere">
      <inherit name="editor_room" />
    </object>
  </object>
  <object name="alley">
    <inherit name="editor_room" />
    <object name="Signlight">
      <inherit name="editor_object" />
      <visible type="boolean">false</visible>
      <usedefaultprefix type="boolean">false</usedefaultprefix>
    </object>
  </object>
  <command name="hello ping">
    <pattern>ping; ping calliope; ping the calliope</pattern>
    <script><![CDATA[
      SetFontName ("'Lucida Console', Monaco, monospace")
      msg ("> ping The Calliope")
      player.PingRate = player.PingBase - player.connection
      on ready {
        msg ("> Reply from The Calliope: time = {player.PingRate}ms")
        on ready {
          SetWebFontName ("Press Start 2P")
        }
      }
    ]]></script>
  </command>
  <verb>
    <property>about</property>
    <pattern>about</pattern>
    <defaultexpression type="string"></defaultexpression>
    <multiobjectmenuempty>  </multiobjectmenuempty>
    <separator type="string"></separator>
    <multiobjectdefault> </multiobjectdefault>
    <multiobjectmenu type="string"></multiobjectmenu>
    <script><![CDATA[
      if (object.parent=Global) {
        if (Shlvl One.isopen) {
          msg ("You know yourself well enough to know that you can either dig through trash or you can think, but you can't do both. Maybe when you're back at the CONSOLE, away from the mess, you can think more clearly.<br/>")
          return (null)
        }
      }
      if (not IsDefined("object2")) {
        object2 = null
      }
      switch (TypeOf(object, this.property)) {
        case ("script") {
          if (object2 = null) {
            do (object, this.property)
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("string") {
          if (object2 = null) {
            msg (GetString(object, this.property))
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("scriptdictionary") {
          if (object2 <> null) {
            HandleMultiVerb (object, this.property, object2, this.multiobjectdefault)
          }
          else {
            objectlist = ListCombine (ScopeReachableInventory(), ScopeReachableNotHeld())
            excludelist = NewObjectList()
            list add (excludelist, game.pov)
            list add (excludelist, object)
            candidates = ListExclude(RemoveSceneryObjects(objectlist), excludelist)
            if (ListCount(candidates) = 0) {
              msg (this.multiobjectmenuempty)
            }
            else {
              game.pov.multiverb = this.property
              game.pov.multiverbobject = object
              game.pov.multiverbobjectdefault = this.multiobjectdefault
              ShowMenu (this.multiobjectmenu, candidates, true) {
                if (result <> null) {
                  HandleMultiVerb (game.pov.multiverbobject, game.pov.multiverb, GetObject(result), game.pov.multiverbobjectdefault)
                  game.pov.multiverb = null
                  game.pov.multiverbobject = null
                  game.pov.multiverbobjectdefault = null
                }
              }
            }
          }
        }
        case ("null") {
          if (this.defaulttext <> null) {
            msg (this.defaulttext)
          }
          else if (this.defaulttemplate <> null) {
            msg (DynamicTemplate(this.defaulttemplate, object))
          }
          else if (this.defaultexpression <> null) {
            params = NewDictionary()
            dictionary add (params, "object", object)
            msg (Eval(this.defaultexpression, params))
          }
          else {
            error ("No verb response defined")
          }
        }
        default {
          msg (" ")
        }
      }
    ]]></script>
  </verb>
  <object name="Global">
    <inherit name="editor_room" />
    <usedefaultprefix type="boolean">false</usedefaultprefix>
    <object name="Grotto Vale">
      <inherit name="editor_object" />
      <visible type="boolean">false</visible>
      <usedefaultprefix type="boolean">false</usedefaultprefix>
      <displayverbs type="stringlist" />
      <inventoryverbs type="stringlist" />
      <about type="script">
        firsttime {
          msg ("You know most of Grotto Vale is all moss and threadsilk, hanging off of miles of walls of towering ruins all the way up to the sea. You've heard of cities aglow with hundreds of signlights, crystal canalbeds shimmering in the distant sun. But you've spent most of your time in the middle of nowhere. ")
          player.curiosity = player.curiosity+1
        }
        otherwise {
          msg ("You're pretty sure you like Grotto Vale. IThe rain is always a little salty, but you get used to it.")
        }
      </about>
    </object>
    <object name="Calliope">
      <inherit name="editor_object" />
      <visible type="boolean">false</visible>
      <usedefaultprefix type="boolean">false</usedefaultprefix>
      <prefix>the</prefix>
      <gender>she</gender>
      <article>she</article>
      <possessive>hers</possessive>
      <about type="script"><![CDATA[
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("You wonder if the worldmind can understand how people feel about its sad, lonely abandoned places. You wonder if people can understand how it feels to be a sad, lonely and abandoned place.<br/><br/>. . . . It's probably not so bad, as long as there's more to the Calliope than that.<br/>")
        }
        otherwise {
          msg ("You wonder if the worldmind can understand how people feel about its sad, lonely abandoned places. You wonder if people can understand how it feels to be a sad, lonely and abandoned place.<br/><br/>. . . . It's probably not so bad, as long as there's more to the Calliope than that.<br/>")
        }
      ]]></about>
    </object>
    <object name="Sea">
      <inherit name="editor_object" />
      <visible type="boolean">false</visible>
      <usedefaultprefix type="boolean">false</usedefaultprefix>
      <prefix>the</prefix>
      <alias>Undersea; overhead sea; thresher sea</alias>
      <about type="script"><![CDATA[
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("It's always so humid in Grotto Vale. Sometimes in the dark, you imagine you can hear the inland sea, all the way up there. It's like a scab over the whole valley, except that scabs generally fall off when the healing's done.<br/>")
        }
        otherwise {
          msg ("It's always so humid in Grotto Vale. Sometimes in the dark, you imagine you can hear the inland sea, all the way up there. It's like a scab over the whole valley, except that scabs generally fall off when the healing's done.<br/>")
        }
      ]]></about>
    </object>
    <object name="Long Night">
      <inherit name="editor_object" />
      <visible type="boolean">false</visible>
      <usedefaultprefix type="boolean">false</usedefaultprefix>
      <prefix>the</prefix>
      <about type="script">
        firsttime {
          msg ("You're already living it, you don't need to think about it too.")
          player.connection = player.connection+1
        }
        otherwise {
          msg ("You're already living it, you don't need to think about it too.")
        }
      </about>
      <remember type="script"><![CDATA[
        firsttime {
          msg ("You don't need to remember something that you're still going through.<br/><br/>That's what you need to tell yourself, because you certainly don't remember this entire nightmare start to finish.<br/>")
          player.curiosity = player.curiosity+2
        }
        otherwise {
          msg ("You don't need to remember something that you're still going through.<br/><br/>That's what you need to tell yourself, because you certainly don't remember this entire nightmare start to finish.<br/>")
        }
      ]]></remember>
    </object>
    <object name="Visions">
      <inherit name="editor_object" />
      <inherit name="plural" />
      <visible type="boolean">false</visible>
      <usedefaultprefix type="boolean">false</usedefaultprefix>
      <prefix>the</prefix>
      <about type="script"><![CDATA[
        msg ("You're popular with them. You've learned to adjust to that.<br/>")
      ]]></about>
    </object>
    <object name="Key">
      <inherit name="editor_object" />
      <visible type="boolean">false</visible>
      <usedefaultprefix type="boolean">false</usedefaultprefix>
      <prefix>the</prefix>
      <admintools type="boolean">false</admintools>
      <alias>Key</alias>
      <about type="script"><![CDATA[
        msg ("It feels heavy on your sternum. You kind of like it. <br/>")
      ]]></about>
      <takeoff type="script"><![CDATA[
        msg ("You can't bring yourself to. Real or not, you don't want to lose it.  <br/>")
      ]]></takeoff>
      <examine type="script"><![CDATA[
        if (Key.admintools) {
          msg ("You find some tiny numbers and letters carefully etched into the key:<br/><br/>G&T IDENT 0248<br/>CONNECT PROMISE<br/>SERIAL 0004<br/>TOKENS REMAIN 0000<br/>")
        }
        else {
          msg ("You find some tiny numbers and letters carefully etched into the key:<br/><br/>G&T IDENT 0248<br/>CONNECT PROMISE<br/>SERIAL 0004<br/>TOKENS REMAIN 0001<br/>")
        }
      ]]></examine>
    </object>
    <object name="Forest Ruin">
      <inherit name="editor_object" />
      <alias>Forest Ruin; Ruins; Ruin</alias>
      <about type="script"><![CDATA[
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("Nobody knows when these ruins were grown here, but they fill the entire valley.<br/>")
        }
        otherwise {
          msg ("Nobody knows when these ruins were grown here, but they fill the entire valley.<br/>")
        }
      ]]></about>
    </object>
    <object name="Fossil Trash">
      <inherit name="editor_object" />
      <about type="script">
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("They say it would take thousands of moons for this much trash to build up, even if everyone in the entire Calliope threw out everything they have. There are a lot of theories about how it got here, but you think whoever used to live here just had a lot they wished they could get rid of.")
        }
        otherwise {
          msg ("They say it would take thousands of moons for this much trash to build up, even if everyone in the entire Calliope threw out everything they have. There are a lot of theories about how it got here, but you think whoever used to live here just had a lot they wished they could get rid of.")
        }
      </about>
    </object>
    <object name="Grove Marble">
      <inherit name="editor_object" />
      <about type="script">
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("Turns out all this post-magic petrified wood is good for all sorts of things, but you always felt a little weird about taking something that used to be that much taller, older, and more useful than you and turning it into interior decor. ")
        }
        otherwise {
          msg ("Turns out all this post-magic petrified wood is good for all sorts of things, but you always felt a little weird about taking something that used to be that much taller, older, and more useful than you and turning it into interior decor. ")
        }
      </about>
    </object>
    <object name="Diadem Borough">
      <inherit name="editor_object" />
      <about type="script"><![CDATA[
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("The city of masks, the city of visions. Diadem Borough is the biggest island hill in the valley. You used to have your heart set on visiting.<br/>")
        }
        otherwise {
          msg ("The city of masks, the city of visions. Diadem Borough is the biggest island hill in the valley. You used to have your heart set on visiting.<br/>")
        }
      ]]></about>
    </object>
    <object name="Grull Trawl">
      <inherit name="editor_object" />
      <alt type="stringlist">
        <value><![CDATA[Grull & Trawl]]></value>
      </alt>
      <alias><![CDATA[Grull & Trawl; Grull and Trawl; Grull Trawl: Grull&Trawl; GrullTrawl]]></alias>
      <about type="script"><![CDATA[
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("Grull & Trawl Limited. They're called that because they didn't have a grove marble license when they first started out, so they were only able to build very small, very magic-hungry contraptions. Changing at this point would probably take a galling amount of paperwork. The snailsweeper was their idea. Maybe their best idea.")
        }
        otherwise {
          msg ("Grull & Trawl Limited. They're called that because they didn't have a grove marble license when they first started out, so they were only able to build very small, very magic-hungry contraptions. Changing at this point would probably take a galling amount of paperwork. The snailsweeper was their idea. Maybe their best idea.")
        }
      ]]></about>
    </object>
    <object name="Island Hill">
      <inherit name="editor_object" />
      <alt type="stringlist">
        <value>Island Hills</value>
      </alt>
      <about type="script"><![CDATA[
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("It gets so windy up there on the archipelago. It's like it holds its breath down here just so it can gust and bellow up there. The overhead sea is just the Thresher  Sea up there, and the waves might only be a vision, but they're so loud when they crash against the shore. <br/><br/>In Grotto Vale they don't like to call it the Thresher, but in Grotto Vale nobody ever has to see anything fall in.<br/>")
        }
        otherwise {
          msg ("It gets so windy up there on the archipelago. It's like it holds its breath down here just so it can gust and bellow up there. The overhead sea is just the Thresher  Sea up there, and the waves might only be a vision, but they're so loud when they crash against the shore. <br/><br/>In Grotto Vale they don't like to call it the Thresher, but in Grotto Vale nobody ever has to see anything fall in.<br/>")
        }
      ]]></about>
    </object>
    <object name="Architect">
      <inherit name="editor_object" />
      <about type="script">
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("The Architect runs the School of Public Harmony and oversees the grove marble harvest. You've heard he's always surrounded by visions when he makes public appearances, just like you.")
        }
        otherwise {
          msg ("The Architect runs the School of Public Harmony and oversees the grove marble harvest. You've heard he's always surrounded by visions when he makes public appearances, just like you.")
        }
      </about>
    </object>
    <object name="Custodian">
      <inherit name="editor_object" />
      <alt type="stringlist">
        <value>The Custodian</value>
        <value>The Head Scholar Custodian</value>
      </alt>
      <about type="script">
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("The Head Scholar Custodian. Easily the most popular figure on the Diadem Borough political stage. She wears a massive tinted moon glass lens over her face and only communicates in a form of sign she made up herself. Personally, you think she's a litle overrated. ")
        }
        otherwise {
          msg ("The Head Scholar Custodian. Easily the most popular figure on the Diadem Borough political stage. She wears a massive tinted moon glass lens over her face and only communicates in a form of sign she made up herself. Personally, you think she's a litle overrated. ")
        }
      </about>
    </object>
    <object name="Webmaster">
      <inherit name="editor_object" />
      <alt type="stringlist">
        <value>The Webmaster</value>
      </alt>
      <about type="script"><![CDATA[
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("The Webmaster is an important part of the team taking care of Diadem Borough and the valley at large.<br/><br/>You honestly have no idea what he does aside from scaring children. <br/>")
        }
        otherwise {
          msg ("The Webmaster is an important part of the team taking care of Diadem Borough and the valley at large.<br/><br/>You honestly have no idea what he does aside from scaring children. <br/>")
        }
      ]]></about>
    </object>
    <object name="Tree Country">
      <inherit name="editor_object" />
      <alias>Tree Country; Jade; where the trees grow; forest</alias>
      <about type="script"><![CDATA[
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("There's only one place in the Calliope where the trees still grow, You've never seen anything else like it. <br/><br/>You're a little surprised at how fond your memories are of that place.<br/>")
        }
        otherwise {
          msg ("There's only one place in the Calliope where the trees still grow, You've never seen anything else like it. <br/><br/>You're a little surprised at how fond your memories are of that place.<br/>")
        }
      ]]></about>
      <remember type="script"><![CDATA[
        firsttime {
          game.active_play_text = NewStringList()
          game.nowhere_intro = NewStringList()
          player.rememberverb = true
          player.curiosity = player.curiosity+1
          list add (game.nowhere_intro, "It's simply a different world.")
          list add (game.nowhere_intro, "Where the trees still grow.")
          list add (game.nowhere_intro, "You can't imagine a tree would want to grow anywhere else, if it could choose to grow there.")
          list add (game.nowhere_intro, "You can't imagine anyone would choose to be anywhere else, if they could choose to belong there.")
          list add (game.nowhere_intro, "Here in the Vale or up in the Island Hills, out on the Ridge or even up in the Teeth, it's all the same.")
          list add (game.nowhere_intro, "Everywhere you go, you walk upon the Calliope. ")
          list add (game.nowhere_intro, "She's the world beneath your feet.")
          list add (game.nowhere_intro, "Always supporting you.")
          list add (game.nowhere_intro, "But out in the trees, it's different. ")
          list add (game.nowhere_intro, "You walk with her.")
          list add (game.nowhere_intro, "You walk alongside her.")
          list add (game.nowhere_intro, "Among her.")
          list add (game.nowhere_intro, ". . . .")
          list add (game.nowhere_intro, "You were never cut out for it, in the end.")
          list add (game.nowhere_intro, "You never belonged, and you'll never forget.")
          game.after_dialogue_script => {
            Boundary_Lock = False
            BoundaryUnlock
            JS.uiShow ("#txtCommandDiv")
          }
          foreach (item, game.nowhere_intro) {
            list add (game.active_play_text, item)
          }
          on ready {
            anykey
          }
        }
        otherwise {
          msg ("You never belonged, and you'll never forget.<br/>")
        }
      ]]></remember>
    </object>
    <object name="trees">
      <inherit name="editor_object" />
      <alt type="stringlist">
        <value>tree leaves</value>
        <value>leaves</value>
      </alt>
      <about type="script"><![CDATA[
        msg ("At first you didn't mind the visions of trees. They were a pleasant reminder of your time in tree country, so long ago. You cherish those memories.<br/><br/>But as time has pooled around you, your skin has started rebelling against the tickle and itch of twigs and leaf-tips. You constantly have to remind yourself not to scratch, because it isn't real. <br/>")
      ]]></about>
      <remember type="script"><![CDATA[
        firsttime {
          player.curiosity = player.curiosity+2
          player.rememberverb = true
          game.active_play_text = NewStringList()
          game.nowhere_intro = NewStringList()
          player.connection = player.connection+1
          player.care = player.care+1
          list add (game.nowhere_intro, "You remember being so overwhelmed the first time the whole forest around you caught the wind. ")
          list add (game.nowhere_intro, "The dappled light and shadow surged all around you, flickering.")
          list add (game.nowhere_intro, "The moonlight was dry and pale like silk. ")
          list add (game.nowhere_intro, "It was the color of orchids.")
          list add (game.nowhere_intro, "You could practically taste it sparkling on your tongue.")
          list add (game.nowhere_intro, "You were used to the sound and fury of the wind, powering across the sea to the shore.")
          list add (game.nowhere_intro, "But the way it took everything the forest was and just shook it, just lifted everything - !")
          list add (game.nowhere_intro, "For just a moment, as you watched the bow and dazzle of the towering trees. . . . ")
          list add (game.nowhere_intro, "For a moment, you were so certain that all those thousands of jade green leaves. . . .")
          list add (game.nowhere_intro, "were about to part with their branches for good. . . .")
          list add (game.nowhere_intro, ". . . . and become birds.")
          list add (game.nowhere_intro, ". . . .")
          list add (game.nowhere_intro, "You remember the sound of laughter that came, when you blurted the thought out aloud.")
          list add (game.nowhere_intro, "You still don't know if you should smile or choke at a memory like that.")
          game.after_dialogue_script => {
            Boundary_Lock = False
            BoundaryUnlock
            JS.uiShow ("#txtCommandDiv")
          }
          foreach (item, game.nowhere_intro) {
            list add (game.active_play_text, item)
          }
          on ready {
            anykey
          }
        }
        otherwise {
          msg ("You're not sure whether to smile or to choke at a memory like that.<br/>")
        }
      ]]></remember>
    </object>
    <object name="wizardsabout">
      <inherit name="editor_object" />
      <alt type="stringlist">
        <value>Wizards</value>
        <value>Wizard</value>
      </alt>
      <about type="script">
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("They can see as much or as little of you as they want and you'd never even know about it. You're not saying that makes them all dirty little secret scryers or anything. A functioning society needs wizards! But a functional society also needs mushrooms and that doesn't mean you have to let them grow all over you.")
        }
        otherwise {
          msg ("They can see as much or as little of you as they want and you'd never even know about it. You're not saying that makes them all dirty little secret scryers or anything. A functioning society needs wizards! But a functional society also needs mushrooms and that doesn't mean you have to let them grow all over you.")
        }
      </about>
    </object>
    <object name="Salesdriver">
      <inherit name="editor_object" />
      <alt type="stringlist">
        <value>salesdrivers</value>
      </alt>
      <about type="script"><![CDATA[
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("You always used to love hearing the distant jingle of an approaching salesdriver. You never knew what they were peddling until you saw the machine come lumbering, wares hanging off every spare inch of it. <br/><br/>Half the time whatever you bought, boots or beakers, would turn out to glow in the dark. You wouldn't even know what color you got at first. Then the sun would go down and you would become a brilliant beacon of violet and red, parading alone for the evening creatures.<br/><br/>That's one trend you hope never dies.<br/>")
        }
        otherwise {
          msg ("You always used to love hearing the distant jingle of an approaching salesdriver. You never knew what they were peddling until you saw the machine come lumbering, wares hanging off every spare inch of it. <br/><br/>Half the time whatever you bought, boots or beakers, would turn out to glow in the dark. You wouldn't even know what color you got at first. Then the sun would go down and you would become a brilliant beacon of violet and red, parading alone for the evening creatures.<br/><br/>That's one trend you hope never dies.<br/>")
        }
      ]]></about>
    </object>
    <object name="signlightabout">
      <inherit name="editor_object" />
      <alt type="stringlist">
        <value>signlight</value>
        <value>signlights</value>
      </alt>
      <about type="script">
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("Nobody knows whether the signlights are gift from the worldmind or from the ancient past, when the forest-ruin was still alive. What's important is that they're real, and so is the light that shines from them. ")
        }
        otherwise {
          msg ("Nobody knows whether the signlights are gift from the worldmind or from the ancient past, when the forest-ruin was still alive. What's important is that they're real, and so is the light that shines from them. ")
        }
      </about>
    </object>
    <object name="Grove Marble License">
      <inherit name="editor_object" />
      <about type="script">
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("Only the Architect's office has the authority to issue grove marble licenses. They say you can barely take home a handful of ruin rubble without inviting a citation. You know better than that. They also say that taking grove marble without a license summons visions that you do not  want to see. You know they're right about that one.")
        }
        otherwise {
          msg ("Only the Architect's office has the authority to issue grove marble licenses. They say you can barely take home a handful of ruin rubble without inviting a citation. You know better than that. They also say that taking grove marble without a license summons visions that you do not  want to see. You know they're right about that one.")
        }
      </about>
    </object>
    <object name="Broken Face">
      <inherit name="editor_object" />
      <alt type="stringlist" />
      <alias>Broken pieces</alias>
      <about type="script">
        firsttime {
          player.care = player.care+1
          msg ("You don't need to think about things that don't matter.")
        }
        otherwise {
          msg ("You don't need to think about things that don't matter.")
        }
      </about>
    </object>
    <object name="Nap Head">
      <inherit name="editor_object" />
      <inherit name="namedmale" />
      <visible type="boolean">false</visible>
      <about type="script">
        if (game.intro_ending) {
          firsttime {
            msg ("He's not real. You can ignore him and it won't even matter.")
            player.curiosity = player.curiosity+1
          }
          otherwise {
            msg ("He's not real. You can ignore him and it won't even matter.")
          }
        }
      </about>
    </object>
    <object name="Worldmind">
      <inherit name="editor_object" />
      <about type="script">
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("Living in a mindful world certainly keeps  you on your toes, but you have a feeling that a mindless world would be somehow worse.")
        }
        otherwise {
          msg ("Living in a mindful world certainly keeps  you on your toes, but you have a feeling that a mindless world would be somehow worse.")
        }
      </about>
    </object>
    <object name="Lantern Siren">
      <inherit name="editor_object" />
      <about type="script"><![CDATA[
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("They have a bad reputation, but it's not their fault that frightened people will follow any light you put in front of them. Nothing is their fault. <br/><br/>Anyone who's ever seen one knows that. They're gentle creatures. <br/><br/>They're beautiful. <br/>")
        }
        otherwise {
          msg ("So beautiful and round.")
        }
      ]]></about>
    </object>
    <object name="Moon">
      <inherit name="editor_object" />
      <about type="script">
        firsttime {
          player.curiosity = player.curiosity+1
          msg ("You wonder what color the moon is now, out in the real sky over the real Calliope.")
        }
        otherwise {
          msg ("You wonder what color the moon is now, out in the real sky over the real Calliope.")
        }
      </about>
    </object>
    <object name="Grazing Mode">
      <inherit name="editor_object" />
      <about type="script"><![CDATA[
        msg ("This feature was the entire impetus for the Snailsweeper concept:<br/>A touring machine that can't get stranded in the dark. . . .<br/>. . . . so you can't either.<br/>")
      ]]></about>
    </object>
    <object name="onionsabout">
      <inherit name="editor_object" />
      <alias>Onions</alias>
      <about type="script"><![CDATA[
        msg ("They know how to dig their tendrils into places where they can't get yanked out. If you manage to get rid of them, they grow back. <br/>")
      ]]></about>
      <remember type="script"><![CDATA[
        msg ("You do enough of that in your journal. <br/>")
      ]]></remember>
    </object>
  </object>
  <object name="welcome">
    <inherit name="editor_room" />
    <firstenter type="script"><![CDATA[
      welcome.visited = true
      SetTimeout (2) {
        SetAlignment ("center")
        SetForegroundColour ("Aqua")
        msg ("Protected by its overhead sea, <br/>home to Calliope's cherished visions, <br/>always nice and quiet:<br/>")
        SetTimeout (2) {
          msg ("  Grotto Vale is the safest place in the entire Calliope.<br/>")
          SetTimeout (3) {
            msg ("It's also dark, filled with trash, and easy to get lost in. <br/>")
            SetTimeout (3) {
              msg ("A while back, two of Grotto Vale’s best and cleverest <br/>dreamed up a better way to travel the valley floor.  <br/>")
              SetTimeout (3) {
                msg ("It would drag its belly all across the forest ruin <br/> so nobody else has to.<br/>")
                SetTimeout (3) {
                  msg ("It would eat up all the trash in its path<br/> so nobody else has to. <br/>")
                  SetTimeout (3) {
                    msg ("It would stay with you, no matter what<br/> so nobody else has to. <br/>")
                    SetTimeout (3) {
                      msg ("For the empty places where nobody sweeps....  <br/>")
                      SetTimeout (2) {
                        msg ("count on your {color:red:Snailsweeper}. <br/> <br/>")
                        SetTimeout (4) {
                          SetAlignment ("left")
                          on ready {
                            SetForegroundColour ("White")
                            msg ("[Press any key to continue.]")
                            JS.eval ("$('#endWaitDiv').hide();")
                            wait {
                              MoveObject (player, nowhere)
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    ]]></firstenter>
  </object>
  <verb>
    <property>takeoff</property>
    <pattern>take off</pattern>
    <defaultexpression>WriteVerb(game.pov, "can't") + " take off " + object.article + "."</defaultexpression>
    <scope>Key</scope>
    <script><![CDATA[
      if (not IsDefined("object2")) {
        object2 = null
      }
      switch (TypeOf(object, this.property)) {
        case ("script") {
          if (object2 = null) {
            do (object, this.property)
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("string") {
          if (object2 = null) {
            msg (GetString(object, this.property))
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("scriptdictionary") {
          if (object2 <> null) {
            HandleMultiVerb (object, this.property, object2, this.multiobjectdefault)
          }
          else {
            objectlist = ListCombine (ScopeReachableInventory(), ScopeReachableNotHeld())
            excludelist = NewObjectList()
            list add (excludelist, game.pov)
            list add (excludelist, object)
            candidates = ListExclude(RemoveSceneryObjects(objectlist), excludelist)
            if (ListCount(candidates) = 0) {
              msg (this.multiobjectmenuempty)
            }
            else {
              game.pov.multiverb = this.property
              game.pov.multiverbobject = object
              game.pov.multiverbobjectdefault = this.multiobjectdefault
              ShowMenu (this.multiobjectmenu, candidates, true) {
                if (result <> null) {
                  HandleMultiVerb (game.pov.multiverbobject, game.pov.multiverb, GetObject(result), game.pov.multiverbobjectdefault)
                  game.pov.multiverb = null
                  game.pov.multiverbobject = null
                  game.pov.multiverbobjectdefault = null
                }
              }
            }
          }
        }
        case ("null") {
          if (this.defaulttext <> null) {
            msg (this.defaulttext)
          }
          else if (this.defaulttemplate <> null) {
            msg (DynamicTemplate(this.defaulttemplate, object))
          }
          else if (this.defaultexpression <> null) {
            params = NewDictionary()
            dictionary add (params, "object", object)
            msg (Eval(this.defaultexpression, params))
          }
          else {
            error ("No verb response defined")
          }
        }
        default {
          msg (" ")
        }
      }
    ]]></script>
  </verb>
  <object name="start">
    <inherit name="editor_room" />
    <beforeenter type="script">
      game.boundary_lock = true
    </beforeenter>
    <firstenter type="script">
      msg ("[Press any key to connect.]")
      JS.eval ("$('#endWaitDiv').hide();")
      wait {
        ClearScreen
        MoveObject (player, cmd)
      }
    </firstenter>
    <object name="player">
      <inherit name="editor_object" />
      <attr name="feature_startscript" type="boolean">false</attr>
      <gender>you</gender>
      <article>you</article>
      <possessive>your</possessive>
      <usedefaultprefix />
      <wantskettle type="boolean">false</wantskettle>
      <alias>you; me</alias>
      <lcbcuddles type="int">0</lcbcuddles>
      <askedruok type="int">0</askedruok>
      <attr name="pov_look" type="string"></attr>
      <PingBase type="int">100</PingBase>
      <curiosity type="int">0</curiosity>
      <PingRate type="int">0</PingRate>
      <care type="int">0</care>
      <connection type="int">0</connection>
      <attr name="host_fear" type="int">100</attr>
      <attr name="host_lonely" type="int">100</attr>
      <attr name="host_fearmod" type="int">-50</attr>
      <attr name="host_lonelymod" type="int">50</attr>
      <drop type="boolean">false</drop>
      <about type="script">
        on ready {
          aboutyou
        }
      </about>
      <ondrop type="script">
        // curiosity gives access to more information as time goes on, so it's okay for it to pile up
        // care shows more vulnerability and emotion from the PC; high care unlocks true ending
        // connection enables PC to share more of what they want to share with you; higher connection shows more images and reduces friction with PC
        // higher loneliness makes PC act more crazy
        // higher fear makes PC act more helpless
      </ondrop>
      <hug type="script"><![CDATA[
        firsttime {
          msg ("All on their own, your arms come up like a shield around you. They squeeze a little.<br/><br/>You let them hold you. You always do.<br/>")
          player.care = player.care+5
        }
        otherwise {
          msg ("All on their own, your arms come up like a shield around you. They squeeze a little.<br/><br/>You let them hold you. You always do.<br/>")
        }
      ]]></hug>
      <rememberverb type="boolean">false</rememberverb>
      <remember type="script"><![CDATA[
        firsttime {
          game.active_play_text = NewStringList()
          game.nowhere_intro = NewStringList()
          player.connection = player.connection+1
          player.care = player.care+1
          player.rememberverb = true
          list add (game.nowhere_intro, "Sometimes you wish you could be sure that you remember yourself fully.")
          list add (game.nowhere_intro, "Sometimes you wish you remembered yourself less. ")
          list add (game.nowhere_intro, "It always seems to depend on which parts you happen to remember first.")
          list add (game.nowhere_intro, ". . . .")
          list add (game.nowhere_intro, "You're not looking forward to remembering whatever you are right now.")
          game.after_dialogue_script => {
            Boundary_Lock = False
            BoundaryUnlock
            JS.uiShow ("#txtCommandDiv")
          }
          foreach (item, game.nowhere_intro) {
            list add (game.active_play_text, item)
          }
          on ready {
            anykey
          }
        }
        otherwise {
          msg ("You're not looking forward to remembering whatever you are right now.<br/>")
        }
        player.rememberverb = true
      ]]></remember>
    </object>
  </object>
  <object name="ONE TIME TEST">
    <inherit name="editor_room" />
    <firstenter type="script">
      msg ("Ready.")
    </firstenter>
    <onexit type="script">
    </onexit>
    <beforeenter type="script">
      //
    </beforeenter>
    <command name="testcredits">
      <pattern>testcredits</pattern>
      <script>
        introendcredits
      </script>
    </command>
    <command name="testleaves">
      <pattern>testleaves</pattern>
      <script>
        JS.eval ("window.cachedAudio7.play();")
      </script>
    </command>
    <command name="test intro end">
      <pattern>test intro end</pattern>
      <script><![CDATA[
        game.active_play_text = NewStringList()
        game.nowhere_intro = NewStringList()
        list add (game.nowhere_intro, ". . . ?")
        list add (game.nowhere_intro, "There's a leaf of paper here.")
        list add (game.nowhere_intro, "It's your handwriting.")
        list add (game.nowhere_intro, "You read it:")
        foreach (item, game.nowhere_intro) {
          list add (game.active_play_text, item)
        }
        on ready {
          anykey
        }
        game.after_dialogue_script => {
          game.active_play_text = NewStringList()
          game.nowhere_intro = NewStringList()
          list add (game.nowhere_intro, "\"In the world you're from")
          list add (game.nowhere_intro, "Where you thought you belonged")
          list add (game.nowhere_intro, "So long ago<br/>")
          list add (game.nowhere_intro, "In the world you're from")
          list add (game.nowhere_intro, "You remembered for so long")
          list add (game.nowhere_intro, "Places other people know")
          list add (game.nowhere_intro, "Places you're not for")
          list add (game.nowhere_intro, "Places you can't go\"")
          foreach (item, game.nowhere_intro) {
            list add (game.active_play_text, item)
          }
          on ready {
            JS.eval ("window.cachedAudio3.play();")
            SetFontName ("'Palatino Linotype', 'Book Antiqua', Palatino, serif")
            SetFontSize (16)
            intheworld
          }
          game.after_dialogue_script => {
            SetWebFontName ("Press Start 2P")
            SetFontSize (12)
            game.active_play_text = NewStringList()
            game.nowhere_intro = NewStringList()
            list add (game.nowhere_intro, ". . . .")
            list add (game.nowhere_intro, ". . . .")
            list add (game.nowhere_intro, "You suppose you remember writing that.")
            list add (game.nowhere_intro, "You suppose you shouldn't be surprised that Calliope's throwing everything in your face again.")
            list add (game.nowhere_intro, "You suppose. . . . she's always going to find a way to do that.")
            list add (game.nowhere_intro, "You suppose. . . .")
            list add (game.nowhere_intro, ". . . .")
            list add (game.nowhere_intro, ". . . .you shouldn't just hide in the shell forever.")
            list add (game.nowhere_intro, "You should get back in the driver's seat.")
            list add (game.nowhere_intro, ". . . . And you will.")
            list add (game.nowhere_intro, "When you're ready.")
            list add (game.nowhere_intro, "If only so the snailsweeper can graze.")
            foreach (item, game.nowhere_intro) {
              list add (game.active_play_text, item)
            }
            on ready {
              anykey
              player.askedruok = 1
            }
            game.after_dialogue_script => {
              introendcredits
            }
          }
        }
      ]]></script>
    </command>
    <command name="testimage">
      <pattern>testimage</pattern>
      <scope>ONE TIME TEST</scope>
      <script><![CDATA[
        // https://i.imgur.com/qwEjfz4.jpeg
        // img_url = "https://i.imgur.com/f7pKuRe.gif"
        // unique_id = "questFrameImg_" + CStr(RandomInt(1000, 9999))
        // JS.eval ("var uniqueId = '" + unique_id + "'; var img = $('<img id=\"' + uniqueId + '\" />').css({display:'block',margin:'0 auto',maxWidth:'100%',maxHeight:'300px'}).appendTo('#divOutput'); img.attr('src', '" + img_url + "').show(); $('body').css('padding-top','300px');")
        // JS.eval ("var newId = 'questFrameImg_' + new Date().getTime(); var img = $('<img id=\"' + newId + '\" />').css({display:'block',margin:'0 auto',maxWidth:'100%',maxHeight:'300px'}).appendTo('#divOutput'); img.attr('src', 'https://i.imgur.com/f7pKuRe.gif').show(); $('body').css('padding-top','300px'); setTimeout(function() { $('#divOutput').scrollTop($('#divOutput')[0].scrollHeight); }, 50);")
        msg ("msg")
        // Define your image URL
        img_url = "https://i.imgur.com/f7pKuRe.gif"
        JS.eval ("var newDiv = $('<div style=\"text-align:center; margin:10px 0;\"></div>'); var img = $('<img src=\"" + img_url + "\" style=\"display:block; margin:0 auto; max-width:100%; max-height:300px;\" />'); newDiv.append(img); var last = $('#divOutput div').last(); if (last.length) { last.after(newDiv); } else { $('#divOutput').append(newDiv); } setTimeout(function() { $('#divOutput').scrollTop($('#divOutput')[0].scrollHeight); }, 50);")
        // wait {
          // img_url = "https://i.imgur.com/qwEjfz4.jpeg"
          // JS.eval ("var newDiv = $('<div style=\"text-align:center; margin:10px 0;\"></div>'); var img = $('<img src=\"" + img_url + "\" style=\"display:block; margin:0 auto; max-width:100%; max-height:300px;\" />'); newDiv.append(img); var last = $('#divOutput div').last(); if (last.length) { last.after(newDiv); } else { $('#divOutput').append(newDiv); } setTimeout(function() { $('#divOutput').scrollTop($('#divOutput')[0].scrollHeight); }, 50);")
          // }
      ]]></script>
    </command>
    <command name="testfear">
      <pattern>testfear</pattern>
      <script>
        msg ("{player.host_fear}")
      </script>
    </command>
    <command name="testcare">
      <pattern>testcare</pattern>
      <script>
        msg ("{player.care}")
      </script>
    </command>
    <command name="testconnection">
      <pattern>testconnection</pattern>
      <script>
        msg ("{player.connection}")
      </script>
    </command>
    <command name="testlonely">
      <pattern>testlonely</pattern>
      <script>
        pc_statupdate
        msg ("{player.host_lonely}")
      </script>
    </command>
    <command>
      <pattern>testconsole</pattern>
      <script>
        game.shellup4 = 1
        UpToConsole (4)
      </script>
    </command>
    <command>
      <pattern>testbg</pattern>
      <script>
        JS.eval ("$('body').css('background-image', 'url(\"" + GetFileURL("calliopemarginwatching.png") + "\")');")
        JS.eval ("$('body').css('background-image', 'url(\"" + GetFileURL("calliopemarginnormal.png") + "\")');")
      </script>
    </command>
    <command>
      <pattern>teststatupdate</pattern>
      <script>
        pc_statupdate
      </script>
    </command>
    <command>
      <scope>changestat</scope>
      <pattern>changestat</pattern>
      <script>
        player.connection = player.connection+1
      </script>
    </command>
    <command>
      <pattern>testdriverseat</pattern>
      <script>
        JS.uiHide ("#txtCommandDiv")
        driverseat
      </script>
    </command>
  </object>
  <command name="player type test">
    <scope>ONE TIME TEST</scope>
    <pattern>typetest</pattern>
    <script><![CDATA[
      game.typing_test = NewStringList()
      while (ListCount(game.typing_test) > 0) {
        list remove (someobject.somelist, StringListItem(someobject.somelist, 0))
      }
      on ready {
        game.ott_test = true
        msg ("Start typing \"test\"")
        typingtest
      }
    ]]></script>
  </command>
  <verb>
    <property>flipto</property>
    <pattern>flip to</pattern>
    <defaultexpression>WriteVerb(game.pov, "can't") + " flip to " + object.article + "."</defaultexpression>
    <script><![CDATA[
      if (not IsDefined("object2")) {
        object2 = null
      }
      switch (TypeOf(object, this.property)) {
        case ("script") {
          if (object2 = null) {
            do (object, this.property)
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("string") {
          if (object2 = null) {
            msg (GetString(object, this.property))
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("scriptdictionary") {
          if (object2 <> null) {
            HandleMultiVerb (object, this.property, object2, this.multiobjectdefault)
          }
          else {
            objectlist = ListCombine (ScopeReachableInventory(), ScopeReachableNotHeld())
            excludelist = NewObjectList()
            list add (excludelist, game.pov)
            list add (excludelist, object)
            candidates = ListExclude(RemoveSceneryObjects(objectlist), excludelist)
            if (ListCount(candidates) = 0) {
              msg (this.multiobjectmenuempty)
            }
            else {
              game.pov.multiverb = this.property
              game.pov.multiverbobject = object
              game.pov.multiverbobjectdefault = this.multiobjectdefault
              ShowMenu (this.multiobjectmenu, candidates, true) {
                if (result <> null) {
                  HandleMultiVerb (game.pov.multiverbobject, game.pov.multiverb, GetObject(result), game.pov.multiverbobjectdefault)
                  game.pov.multiverb = null
                  game.pov.multiverbobject = null
                  game.pov.multiverbobjectdefault = null
                }
              }
            }
          }
        }
        case ("null") {
          if (this.defaulttext <> null) {
            msg (this.defaulttext)
          }
          else if (this.defaulttemplate <> null) {
            msg (DynamicTemplate(this.defaulttemplate, object))
          }
          else if (this.defaultexpression <> null) {
            params = NewDictionary()
            dictionary add (params, "object", object)
            msg (Eval(this.defaultexpression, params))
          }
          else {
            error ("No verb response defined")
          }
        }
        default {
          msg (" ")
        }
      }
    ]]></script>
  </verb>
  <verb>
    <property>return</property>
    <pattern>return</pattern>
    <defaultexpression>WriteVerb(game.pov, "can't") + " return " + object.article + "."</defaultexpression>
    <script><![CDATA[
      if (not IsDefined("object2")) {
        object2 = null
      }
      switch (TypeOf(object, this.property)) {
        case ("script") {
          if (object2 = null) {
            do (object, this.property)
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("string") {
          if (object2 = null) {
            msg (GetString(object, this.property))
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("scriptdictionary") {
          if (object2 <> null) {
            HandleMultiVerb (object, this.property, object2, this.multiobjectdefault)
          }
          else {
            objectlist = ListCombine (ScopeReachableInventory(), ScopeReachableNotHeld())
            excludelist = NewObjectList()
            list add (excludelist, game.pov)
            list add (excludelist, object)
            candidates = ListExclude(RemoveSceneryObjects(objectlist), excludelist)
            if (ListCount(candidates) = 0) {
              msg (this.multiobjectmenuempty)
            }
            else {
              game.pov.multiverb = this.property
              game.pov.multiverbobject = object
              game.pov.multiverbobjectdefault = this.multiobjectdefault
              ShowMenu (this.multiobjectmenu, candidates, true) {
                if (result <> null) {
                  HandleMultiVerb (game.pov.multiverbobject, game.pov.multiverb, GetObject(result), game.pov.multiverbobjectdefault)
                  game.pov.multiverb = null
                  game.pov.multiverbobject = null
                  game.pov.multiverbobjectdefault = null
                }
              }
            }
          }
        }
        case ("null") {
          if (this.defaulttext <> null) {
            msg (this.defaulttext)
          }
          else if (this.defaulttemplate <> null) {
            msg (DynamicTemplate(this.defaulttemplate, object))
          }
          else if (this.defaultexpression <> null) {
            params = NewDictionary()
            dictionary add (params, "object", object)
            msg (Eval(this.defaultexpression, params))
          }
          else {
            error ("No verb response defined")
          }
        }
        default {
          msg (" ")
        }
      }
    ]]></script>
  </verb>
  <verb>
    <property>examine</property>
    <pattern>examine</pattern>
    <defaultexpression>WriteVerb(game.pov, "can't") + " examine " + object.article + "."</defaultexpression>
    <script><![CDATA[
      if (not IsDefined("object2")) {
        object2 = null
      }
      switch (TypeOf(object, this.property)) {
        case ("script") {
          if (object2 = null) {
            do (object, this.property)
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("string") {
          if (object2 = null) {
            msg (GetString(object, this.property))
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("scriptdictionary") {
          if (object2 <> null) {
            HandleMultiVerb (object, this.property, object2, this.multiobjectdefault)
          }
          else {
            objectlist = ListCombine (ScopeReachableInventory(), ScopeReachableNotHeld())
            excludelist = NewObjectList()
            list add (excludelist, game.pov)
            list add (excludelist, object)
            candidates = ListExclude(RemoveSceneryObjects(objectlist), excludelist)
            if (ListCount(candidates) = 0) {
              msg (this.multiobjectmenuempty)
            }
            else {
              game.pov.multiverb = this.property
              game.pov.multiverbobject = object
              game.pov.multiverbobjectdefault = this.multiobjectdefault
              ShowMenu (this.multiobjectmenu, candidates, true) {
                if (result <> null) {
                  HandleMultiVerb (game.pov.multiverbobject, game.pov.multiverb, GetObject(result), game.pov.multiverbobjectdefault)
                  game.pov.multiverb = null
                  game.pov.multiverbobject = null
                  game.pov.multiverbobjectdefault = null
                }
              }
            }
          }
        }
        case ("null") {
          if (this.defaulttext <> null) {
            msg (this.defaulttext)
          }
          else if (this.defaulttemplate <> null) {
            msg (DynamicTemplate(this.defaulttemplate, object))
          }
          else if (this.defaultexpression <> null) {
            params = NewDictionary()
            dictionary add (params, "object", object)
            msg (Eval(this.defaultexpression, params))
          }
          else {
            error ("No verb response defined")
          }
        }
        default {
          msg (" ")
        }
      }
    ]]></script>
  </verb>
  <verb>
    <property>raise</property>
    <pattern>raise</pattern>
    <defaultexpression>WriteVerb(game.pov, "can't") + " raise " + object.article + "."</defaultexpression>
    <script><![CDATA[
      if (not IsDefined("object2")) {
        object2 = null
      }
      switch (TypeOf(object, this.property)) {
        case ("script") {
          if (object2 = null) {
            do (object, this.property)
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("string") {
          if (object2 = null) {
            msg (GetString(object, this.property))
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("scriptdictionary") {
          if (object2 <> null) {
            HandleMultiVerb (object, this.property, object2, this.multiobjectdefault)
          }
          else {
            objectlist = ListCombine (ScopeReachableInventory(), ScopeReachableNotHeld())
            excludelist = NewObjectList()
            list add (excludelist, game.pov)
            list add (excludelist, object)
            candidates = ListExclude(RemoveSceneryObjects(objectlist), excludelist)
            if (ListCount(candidates) = 0) {
              msg (this.multiobjectmenuempty)
            }
            else {
              game.pov.multiverb = this.property
              game.pov.multiverbobject = object
              game.pov.multiverbobjectdefault = this.multiobjectdefault
              ShowMenu (this.multiobjectmenu, candidates, true) {
                if (result <> null) {
                  HandleMultiVerb (game.pov.multiverbobject, game.pov.multiverb, GetObject(result), game.pov.multiverbobjectdefault)
                  game.pov.multiverb = null
                  game.pov.multiverbobject = null
                  game.pov.multiverbobjectdefault = null
                }
              }
            }
          }
        }
        case ("null") {
          if (this.defaulttext <> null) {
            msg (this.defaulttext)
          }
          else if (this.defaulttemplate <> null) {
            msg (DynamicTemplate(this.defaulttemplate, object))
          }
          else if (this.defaultexpression <> null) {
            params = NewDictionary()
            dictionary add (params, "object", object)
            msg (Eval(this.defaultexpression, params))
          }
          else {
            error ("No verb response defined")
          }
        }
        default {
          msg (" ")
        }
      }
    ]]></script>
  </verb>
  <command name="HELP">
    <pattern>HELP</pattern>
    <script><![CDATA[
      if (game.helpstate = 0) {
        msg ("<br/>* [VERB] + [NOUN]<br/>* COMMAND<br/><br/>[ABOUT]<br/><br/>HUG THAT TRASH<br/>")
      }
      else if (game.helpstate = 1) {
        msg ("<br/>* [VERB] + [NOUN]<br/>* COMMAND<br/><br/>[ABOUT]<br/><br/>CONSOLE<br/><br/>SHELL<br/>")
      }
      else if (game.helpstate = 2) {
        msg ("<br/>* [VERB] + [NOUN]<br/>* COMMAND<br/><br/>[ABOUT]<br/><br/>DIG<br/><br/>CONSOLE<br/>")
      }
      else if (game.helpstate = 3) {
        msg ("<br/>* [VERB] + [NOUN]<br/>* COMMAND<br/><br/>[ABOUT]<br/><br/>[READ]<br/><br/>DEEP<br/><br/>CONSOLE<br/>")
      }
      else if (game.helpstate = 31) {
        msg ("<br/>* [VERB] + [NOUN]<br/>* COMMAND<br/><br/>[ABOUT]<br/><br/>[READ]<br/><br/>[FLIP TO]<br/><br/>[RETURN]<br/>")
      }
      else if (game.helpstate = 4) {
        msg ("<br/>* [VERB] + [NOUN]<br/>* COMMAND<br/><br/>[ABOUT]<br/><br/>[EAT]<br/><br/>[UNCORK]<br/><br/>DEEPER<br/>")
      }
      else if (game.helpstate = 5) {
        msg ("<br/>* [VERB] + [NOUN]<br/>* COMMAND<br/><br/>[ABOUT]<br/><br/>CONSOLE<br/>")
      }
      else if (game.helpstate = 6) {
        msg ("<br/>* [VERB] + [NOUN]<br/>* COMMAND<br/><br/>[ABOUT]<br/>[EXAMINE]<br/><br/>CONSOLE<br/>SHELL<br/>PROMISE<br/>")
      }
      else if (game.helpstate = 7) {
        msg ("<br/>* [VERB] + [NOUN]<br/>* COMMAND<br/><br/>[ABOUT]<br/>[RAISE]<br/><br/>CONSOLE<br/>SHELL<br/>")
      }
      else if (game.helpstate = 8) {
        msg ("<br/>* [VERB] + [NOUN]<br/>* COMMAND<br/><br/>[ABOUT]<br/><br/>HUG THAT TRASH<br/>??? ??? ????<br/>")
      }
    ]]></script>
  </command>
  <verb>
    <property>uncork</property>
    <pattern>uncork</pattern>
    <defaultexpression>WriteVerb(game.pov, "can't") + " uncork " + object.article + "."</defaultexpression>
    <script><![CDATA[
      if (not IsDefined("object2")) {
        object2 = null
      }
      switch (TypeOf(object, this.property)) {
        case ("script") {
          if (object2 = null) {
            do (object, this.property)
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("string") {
          if (object2 = null) {
            msg (GetString(object, this.property))
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("scriptdictionary") {
          if (object2 <> null) {
            HandleMultiVerb (object, this.property, object2, this.multiobjectdefault)
          }
          else {
            objectlist = ListCombine (ScopeReachableInventory(), ScopeReachableNotHeld())
            excludelist = NewObjectList()
            list add (excludelist, game.pov)
            list add (excludelist, object)
            candidates = ListExclude(RemoveSceneryObjects(objectlist), excludelist)
            if (ListCount(candidates) = 0) {
              msg (this.multiobjectmenuempty)
            }
            else {
              game.pov.multiverb = this.property
              game.pov.multiverbobject = object
              game.pov.multiverbobjectdefault = this.multiobjectdefault
              ShowMenu (this.multiobjectmenu, candidates, true) {
                if (result <> null) {
                  HandleMultiVerb (game.pov.multiverbobject, game.pov.multiverb, GetObject(result), game.pov.multiverbobjectdefault)
                  game.pov.multiverb = null
                  game.pov.multiverbobject = null
                  game.pov.multiverbobjectdefault = null
                }
              }
            }
          }
        }
        case ("null") {
          if (this.defaulttext <> null) {
            msg (this.defaulttext)
          }
          else if (this.defaulttemplate <> null) {
            msg (DynamicTemplate(this.defaulttemplate, object))
          }
          else if (this.defaultexpression <> null) {
            params = NewDictionary()
            dictionary add (params, "object", object)
            msg (Eval(this.defaultexpression, params))
          }
          else {
            error ("No verb response defined")
          }
        }
        default {
          msg (" ")
        }
      }
    ]]></script>
  </verb>
  <verb>
    <property>spin</property>
    <pattern>spin</pattern>
    <defaultexpression>WriteVerb(game.pov, "can't") + " spin " + object.article + "."</defaultexpression>
    <script><![CDATA[
      if (not IsDefined("object2")) {
        object2 = null
      }
      switch (TypeOf(object, this.property)) {
        case ("script") {
          if (object2 = null) {
            do (object, this.property)
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("string") {
          if (object2 = null) {
            msg (GetString(object, this.property))
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("scriptdictionary") {
          if (object2 <> null) {
            HandleMultiVerb (object, this.property, object2, this.multiobjectdefault)
          }
          else {
            objectlist = ListCombine (ScopeReachableInventory(), ScopeReachableNotHeld())
            excludelist = NewObjectList()
            list add (excludelist, game.pov)
            list add (excludelist, object)
            candidates = ListExclude(RemoveSceneryObjects(objectlist), excludelist)
            if (ListCount(candidates) = 0) {
              msg (this.multiobjectmenuempty)
            }
            else {
              game.pov.multiverb = this.property
              game.pov.multiverbobject = object
              game.pov.multiverbobjectdefault = this.multiobjectdefault
              ShowMenu (this.multiobjectmenu, candidates, true) {
                if (result <> null) {
                  HandleMultiVerb (game.pov.multiverbobject, game.pov.multiverb, GetObject(result), game.pov.multiverbobjectdefault)
                  game.pov.multiverb = null
                  game.pov.multiverbobject = null
                  game.pov.multiverbobjectdefault = null
                }
              }
            }
          }
        }
        case ("null") {
          if (this.defaulttext <> null) {
            msg (this.defaulttext)
          }
          else if (this.defaulttemplate <> null) {
            msg (DynamicTemplate(this.defaulttemplate, object))
          }
          else if (this.defaultexpression <> null) {
            params = NewDictionary()
            dictionary add (params, "object", object)
            msg (Eval(this.defaultexpression, params))
          }
          else {
            error ("No verb response defined")
          }
        }
        default {
          msg (" ")
        }
      }
    ]]></script>
  </verb>
  <turnscript name="Ping Kill">
    <script><![CDATA[
      if (player.PingRate > 200) {
        SetFontName ("'Lucida Console', Monaco, monospace")
        msg ("Host not responding")
        SetTimeout (2) {
          msg ("Retrying. . . .")
          SetTimeout (2) {
            msg (". . . .")
            SetTimeout (2) {
              msg ("DISCONNECTED")
              SetTimeout (1) {
                finish
              }
            }
          }
        }
      }
      else {
        player.connection = player.connection-20
        pc_statupdate
      }
    ]]></script>
  </turnscript>
  <command name="Thank you">
    <pattern>Thank you</pattern>
    <script>
    </script>
  </command>
  <verb>
    <property>hug</property>
    <pattern>hug</pattern>
    <script><![CDATA[
      if (not IsDefined("object2")) {
        object2 = null
      }
      switch (TypeOf(object, this.property)) {
        case ("script") {
          if (object2 = null) {
            do (object, this.property)
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("string") {
          if (object2 = null) {
            msg (GetString(object, this.property))
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("scriptdictionary") {
          if (object2 <> null) {
            HandleMultiVerb (object, this.property, object2, this.multiobjectdefault)
          }
          else {
            objectlist = ListCombine (ScopeReachableInventory(), ScopeReachableNotHeld())
            excludelist = NewObjectList()
            list add (excludelist, game.pov)
            list add (excludelist, object)
            candidates = ListExclude(RemoveSceneryObjects(objectlist), excludelist)
            if (ListCount(candidates) = 0) {
              msg (this.multiobjectmenuempty)
            }
            else {
              game.pov.multiverb = this.property
              game.pov.multiverbobject = object
              game.pov.multiverbobjectdefault = this.multiobjectdefault
              ShowMenu (this.multiobjectmenu, candidates, true) {
                if (result <> null) {
                  HandleMultiVerb (game.pov.multiverbobject, game.pov.multiverb, GetObject(result), game.pov.multiverbobjectdefault)
                  game.pov.multiverb = null
                  game.pov.multiverbobject = null
                  game.pov.multiverbobjectdefault = null
                }
              }
            }
          }
        }
        case ("null") {
          if (this.defaulttext <> null) {
            msg (this.defaulttext)
          }
          else if (this.defaulttemplate <> null) {
            msg (DynamicTemplate(this.defaulttemplate, object))
          }
          else if (this.defaultexpression <> null) {
            params = NewDictionary()
            dictionary add (params, "object", object)
            msg (Eval(this.defaultexpression, params))
          }
          else {
            error ("No verb response defined")
          }
        }
        default {
          msg (" ")
        }
      }
    ]]></script>
  </verb>
  <verb>
    <property>remember</property>
    <pattern>remember</pattern>
    <script><![CDATA[
      if (not IsDefined("object2")) {
        object2 = null
      }
      switch (TypeOf(object, this.property)) {
        case ("script") {
          if (object2 = null) {
            do (object, this.property)
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("string") {
          if (object2 = null) {
            msg (GetString(object, this.property))
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("scriptdictionary") {
          if (object2 <> null) {
            HandleMultiVerb (object, this.property, object2, this.multiobjectdefault)
          }
          else {
            objectlist = ListCombine (ScopeReachableInventory(), ScopeReachableNotHeld())
            excludelist = NewObjectList()
            list add (excludelist, game.pov)
            list add (excludelist, object)
            candidates = ListExclude(RemoveSceneryObjects(objectlist), excludelist)
            if (ListCount(candidates) = 0) {
              msg (this.multiobjectmenuempty)
            }
            else {
              game.pov.multiverb = this.property
              game.pov.multiverbobject = object
              game.pov.multiverbobjectdefault = this.multiobjectdefault
              ShowMenu (this.multiobjectmenu, candidates, true) {
                if (result <> null) {
                  HandleMultiVerb (game.pov.multiverbobject, game.pov.multiverb, GetObject(result), game.pov.multiverbobjectdefault)
                  game.pov.multiverb = null
                  game.pov.multiverbobject = null
                  game.pov.multiverbobjectdefault = null
                }
              }
            }
          }
        }
        case ("null") {
          if (this.defaulttext <> null) {
            msg (this.defaulttext)
          }
          else if (this.defaulttemplate <> null) {
            msg (DynamicTemplate(this.defaulttemplate, object))
          }
          else if (this.defaultexpression <> null) {
            params = NewDictionary()
            dictionary add (params, "object", object)
            msg (Eval(this.defaultexpression, params))
          }
          else {
            error ("No verb response defined")
          }
        }
        default {
          msg (" ")
        }
      }
    ]]></script>
  </verb>
  <type name="defaultgame">
    <enablehyperlinks />
    <echocommand />
    <echohyperlinks />
    <showdescriptiononenter />
    <autodescription />
    <defaultfont>Georgia, serif</defaultfont>
    <defaultfontsize type="int">12</defaultfontsize>
    <defaultbackground>White</defaultbackground>
    <defaultforeground>Black</defaultforeground>
    <defaultlinkforeground>Blue</defaultlinkforeground>
    <backgroundimage type="string"></backgroundimage>
    <setbackgroundopacity type="boolean">false</setbackgroundopacity>
    <backgroundopacity type="double">0.5</backgroundopacity>
    <menufont>Arial</menufont>
    <menufontsize type="int">9</menufontsize>
    <menubackground>White</menubackground>
    <menuforeground>Black</menuforeground>
    <menuhoverbackground>LightGrey</menuhoverbackground>
    <menuhoverforeground>Black</menuhoverforeground>
    <underlinehyperlinks />
    <compassdirections type="stringlist">
      <value>northwest</value>
      <value>north</value>
      <value>northeast</value>
      <value>west</value>
      <value>east</value>
      <value>southwest</value>
      <value>south</value>
      <value>southeast</value>
      <value>up</value>
      <value>down</value>
      <value>in</value>
      <value>out</value>
    </compassdirections>
    <clearframe />
    <timeelapsed type="int">0</timeelapsed>
    <appendobjectdescription type="boolean">false</appendobjectdescription>
    <allobjects type="stringlist">
      <value>all</value>
      <value>everything</value>
    </allobjects>
    <parserignoreprefixes type="stringlist">
      <value>the</value>
      <value>a</value>
      <value>an</value>
    </parserignoreprefixes>
    <displayroomdescriptiononstart />
    <showpanes />
    <showcommandbar />
    <showlocation />
    <statusandcompassattop type="boolean">false</statusandcompassattop>
    <turnoffcompass type="boolean">false</turnoffcompass>
    <turnoffinventory type="boolean">false</turnoffinventory>
    <turnoffplacesandobjects type="boolean">false</turnoffplacesandobjects>
    <borderlesscursor type="boolean">false</borderlesscursor>
    <colourblend type="boolean">false</colourblend>
    <commandpane type="boolean">false</commandpane>
    <customstatuspane type="boolean">false</customstatuspane>
    <panestheme>Classic</panestheme>
    <shadowbox type="boolean">false</shadowbox>
    <respondtogridclicks type="boolean">false</respondtogridclicks>
    <commandcursor><![CDATA[>]]></commandcursor>
    <moneyformat>$!</moneyformat>
    <classiclocation />
    <turnoffsavebutton type="boolean">false</turnoffsavebutton>
    <mapexitwidth type="int">1</mapexitwidth>
    <mapexitcolour>Black</mapexitcolour>
    <setcustomwidth type="boolean">false</setcustomwidth>
    <customwidth type="int">950</customwidth>
    <setcustompadding type="boolean">false</setcustompadding>
    <custompaddingtop type="int">30</custompaddingtop>
    <custompaddingbottom type="int">0</custompaddingbottom>
    <custompaddingleft type="int">20</custompaddingleft>
    <custompaddingright type="int">20</custompaddingright>
    <showborder />
    <showscore type="boolean">false</showscore>
    <showhealth type="boolean">false</showhealth>
    <showmoney type="boolean">false</showmoney>
    <showtitle />
    <autodisplayverbs />
    <clearscreenonroomenter type="boolean">false</clearscreenonroomenter>
    <attr name="autodescription_youarein" type="int">1</attr>
    <attr name="autodescription_youcansee" type="int">2</attr>
    <attr name="autodescription_youcango" type="int">3</attr>
    <attr name="autodescription_description" type="int">4</attr>
    <autodescription_youarein_useprefix />
    <attr name="autodescription_youarein_newline" type="boolean">false</attr>
    <attr name="autodescription_youcansee_newline" type="boolean">false</attr>
    <attr name="autodescription_youcango_newline" type="boolean">false</attr>
    <attr name="autodescription_description_newline" type="boolean">false</attr>
    <changeroom_newline />
    <attr name="command_newline" type="boolean">false</attr>
    <description type="string"></description>
    <languageid>en</languageid>
    <gridmap type="boolean">false</gridmap>
    <mapscale type="int">30</mapscale>
    <mapsize type="int">300</mapsize>
    <attr name="feature_lightdark" type="boolean">false</attr>
    <attr name="feature_pictureframe" type="boolean">false</attr>
    <attr name="feature_limitinventory" type="boolean">false</attr>
    <attr name="feature_asktell" type="boolean">false</attr>
    <attr name="feature_annotations" type="boolean">false</attr>
    <attr name="feature_advancedwearables" type="boolean">false</attr>
    <attr name="feature_advancedscripts" type="boolean">false</attr>
    <deactivatecommandlinks type="boolean">false</deactivatecommandlinks>
    <donotclearmenus type="boolean">false</donotclearmenus>
    <showmenuresponses type="boolean">false</showmenuresponses>
    <multiplecommands type="boolean">false</multiplecommands>
    <publishfileextensions>*.jpg;*.jpeg;*.png;*.gif;*.js;*.wav;*.mp3;*.htm;*.html;*.svg;*.ogg;*.ogv</publishfileextensions>
    <writelogtofile type="boolean">false</writelogtofile>
    <notranscript type="boolean">false</notranscript>
    <savetranscript type="boolean">false</savetranscript>
    <suppressturnscripts />
    <attr name="feature_devmode" type="boolean">false</attr>
    <changedpov type="script">
      InitPOV (oldvalue, game.pov)
    </changedpov>
    <changedsavetranscript type="script">
      if (game.notranscript) {
        KillTranscript
      }
      else if (game.savetranscript) {
        if (not HasAttribute (game, "transcriptname")) {
          game.transcriptname = GetWindowsSafeName(game.gamename)
        }
        JS.enableTranscript (game.transcriptname)
      }
      else {
        JS.disableTranscript ()
      }
      if (HasScript(game, "onchangedsavetranscript")) {
        invoke (game.onchangedsavetranscript)
      }
    </changedsavetranscript>
    <changednotranscript type="script">
      if (game.notranscript) {
        KillTranscript
      }
      else {
        JS.reviveTranscript ()
      }
      if (HasScript(game, "onchangednotranscript")) {
        invoke (game.onchangednotranscript)
      }
    </changednotranscript>
    <textprocessorcommands type="scriptdictionary">
      <item key="if ">
        game.textprocessorcommandresult = ProcessTextCommand_If (section, data)
      </item>
      <item key="either ">
        game.textprocessorcommandresult = ProcessTextCommand_Either (section, data)
      </item>
      <item key="here ">
        game.textprocessorcommandresult = ProcessTextCommand_Here (section, data)
      </item>
      <item key="nothere ">
        game.textprocessorcommandresult = ProcessTextCommand_Here (section, data)
      </item>
      <item key="popup:">
        game.textprocessorcommandresult = ProcessTextCommand_Popup (section, data)
      </item>
      <item key="i:">
        game.textprocessorcommandresult = ProcessTextCommand_Format (section, data)
      </item>
      <item key="b:">
        game.textprocessorcommandresult = ProcessTextCommand_Format (section, data)
      </item>
      <item key="s:">
        game.textprocessorcommandresult = ProcessTextCommand_Format (section, data)
      </item>
      <item key="u:">
        game.textprocessorcommandresult = ProcessTextCommand_Format (section, data)
      </item>
      <item key="colour:">
        game.textprocessorcommandresult = ProcessTextCommand_Colour (section, data)
      </item>
      <item key="color:">
        game.textprocessorcommandresult = ProcessTextCommand_Colour (section, data)
      </item>
      <item key="back:">
        game.textprocessorcommandresult = ProcessTextCommand_Colour (section, data)
      </item>
      <item key="object:">
        game.textprocessorcommandresult = ProcessTextCommand_Object (section, data)
      </item>
      <item key="command:">
        game.textprocessorcommandresult = ProcessTextCommand_Command (section, data)
      </item>
      <item key="page:">
        game.textprocessorcommandresult = ProcessTextCommand_Command (section, data)
      </item>
      <item key="exit:">
        game.textprocessorcommandresult = ProcessTextCommand_Exit (section, data)
      </item>
      <item key="once:">
        game.textprocessorcommandresult = ProcessTextCommand_Once (section, data)
      </item>
      <item key="notfirst:">
        game.textprocessorcommandresult = ProcessTextCommand_NotFirst (section, data)
      </item>
      <item key="random:">
        game.textprocessorcommandresult = ProcessTextCommand_Random (section, data)
      </item>
      <item key="rndalt:">
        game.textprocessorcommandresult = ProcessTextCommand_RandomAlias (section, data)
      </item>
      <item key="img:">
        game.textprocessorcommandresult = ProcessTextCommand_Img (section, data)
      </item>
      <item key="counter:">
        game.textprocessorcommandresult = ProcessTextCommand_Counter (section, data)
      </item>
      <item key="select:">
        game.textprocessorcommandresult = ProcessTextCommand_Select (section, data)
      </item>
      <item key="eval:">
        game.textprocessorcommandresult = ProcessTextCommand_Eval (section, data)
      </item>
      <item key="=">
        game.textprocessorcommandresult = ProcessTextCommand_Eval (section, data)
      </item>
    </textprocessorcommands>
  </type>
  <type name="theme_novella">
    <setcustompadding />
    <showborder type="boolean">false</showborder>
    <showpanes type="boolean">false</showpanes>
    <showlocation type="boolean">false</showlocation>
    <setcustomwidth />
    <customwidth type="int">650</customwidth>
    <custompaddingtop type="int">60</custompaddingtop>
  </type>
  <type name="theme_retro">
    <defaultbackground>Black</defaultbackground>
    <defaultforeground>White</defaultforeground>
    <defaultlinkforeground>White</defaultlinkforeground>
    <defaultfont>'Lucida Console', Monaco, monospace</defaultfont>
    <defaultwebfont>Press Start 2P</defaultwebfont>
    <menufontsize type="int">14</menufontsize>
    <menufont>'Lucida Console', Monaco, monospace</menufont>
    <menubackground>Black</menubackground>
    <menuforeground>White</menuforeground>
    <menuhoverbackground>GreenYellow</menuhoverbackground>
  </type>
  <type name="theme_typewriter">
    <setcustompadding />
    <showborder type="boolean">false</showborder>
    <showpanes type="boolean">false</showpanes>
    <showlocation type="boolean">false</showlocation>
    <setcustomwidth />
    <customwidth type="int">650</customwidth>
    <custompaddingtop type="int">60</custompaddingtop>
    <defaultfont>'Courier New', Courier, monospace</defaultfont>
    <defaultwebfont>Special Elite</defaultwebfont>
  </type>
  <type name="theme_hotdogstand">
    <defaultbackground>Red</defaultbackground>
    <defaultforeground>Yellow</defaultforeground>
    <defaultlinkforeground>Yellow</defaultlinkforeground>
    <defaultfont>'Comic Sans MS', cursive, sans-serif</defaultfont>
    <menufontsize type="int">14</menufontsize>
    <menufont>Impact, Charcoal, sans-serif</menufont>
    <menubackground>Red</menubackground>
    <menuforeground>Yellow</menuforeground>
    <menuhoverbackground>Black</menuhoverbackground>
    <menuhoverforeground>Yellow</menuhoverforeground>
  </type>
  <type name="defaultobject">
    <visible />
    <displayverbs type="stringlist">
      <value>Look at</value>
      <value>Take</value>
    </displayverbs>
    <inventoryverbs type="stringlist">
      <value>Look at</value>
      <value>Use</value>
      <value>Drop</value>
    </inventoryverbs>
    <take type="boolean">false</take>
    <use type="boolean">false</use>
    <givesingle type="boolean">false</givesingle>
    <drop />
    <gender>it</gender>
    <article>it</article>
    <possessive>its</possessive>
    <wornmodifier>worn</wornmodifier>
    <isopen type="boolean">false</isopen>
    <open type="boolean">false</open>
    <close type="boolean">false</close>
    <container type="boolean">false</container>
    <descprefix>{=WriteVerb(game.pov, "be")} in</descprefix>
    <objectslistprefix>{=WriteVerb(game.pov, "can")} see</objectslistprefix>
    <exitslistprefix>{=WriteVerb(game.pov, "can")} go</exitslistprefix>
    <contentsprefix>containing</contentsprefix>
    <description type="string"></description>
    <attr name="implementation_notes" type="string"></attr>
    <scenery type="boolean">false</scenery>
    <hidechildren type="boolean">false</hidechildren>
    <listchildren type="boolean">false</listchildren>
    <usedefaultprefix />
    <volume type="int">0</volume>
    <price type="int">0</price>
    <dark type="boolean">false</dark>
    <lightstrength type="string"></lightstrength>
    <darklevel type="boolean">false</darklevel>
    <attr name="grid_width" type="int">1</attr>
    <attr name="grid_length" type="int">1</attr>
    <attr name="grid_fill">White</attr>
    <attr name="grid_border">Black</attr>
    <attr name="grid_borderwidth" type="int">1</attr>
    <attr name="grid_bordersides" type="int">15</attr>
    <attr name="grid_render" type="boolean">false</attr>
    <attr name="grid_label" type="string"></attr>
    <attr name="grid_label_colour">Black</attr>
    <grid_parent_offset_auto />
    <attr name="grid_parent_offset_x" type="int">0</attr>
    <attr name="grid_parent_offset_y" type="int">0</attr>
    <attr name="pov_alias">me</attr>
    <pov_alt type="stringlist">
      <value>me</value>
      <value>myself</value>
      <value>self</value>
    </pov_alt>
    <attr name="pov_look">Looking good.</attr>
    <attr name="pov_gender">you</attr>
    <attr name="pov_article">yourself</attr>
    <attr name="pov_possessive">your</attr>
    <attr name="feature_usegive" type="boolean">false</attr>
    <attr name="feature_container" type="boolean">false</attr>
    <attr name="feature_switchable" type="boolean">false</attr>
    <attr name="feature_edible" type="boolean">false</attr>
    <attr name="feature_player" type="boolean">false</attr>
    <attr name="feature_lightdark" type="boolean">false</attr>
    <visited type="boolean">false</visited>
    <hasbeenmoved type="boolean">false</hasbeenmoved>
    <timesexamined type="int">0</timesexamined>
    <attr name="not_all" type="boolean">false</attr>
    <changedparent type="script">
      if (game.pov = this) {
        if (IsDefined("oldvalue")) {
          OnEnterRoom (oldvalue)
        }
        else {
          OnEnterRoom (null)
        }
        if (game.gridmap) {
          MergePOVCoordinates
        }
      }
      this.hasbeenmoved = true
    </changedparent>
    <changedisopen type="script">
      if (this.isopen and HasScript(this, "onopen")) {
        do (this, "onopen")
      }
      if (not this.isopen and HasScript(this, "onclose")) {
        do (this, "onclose")
      }
    </changedisopen>
    <changedlocked type="script">
      if (this.locked and HasScript(this, "onlock")) {
        do (this, "onlock")
      }
      if (not this.locked and HasScript(this, "onunlock")) {
        do (this, "onunlock")
      }
    </changedlocked>
    <changedswitchedon type="script">
      if (this.switchedon and HasScript(this, "onswitchon")) {
        do (this, "onswitchon")
      }
      if (not this.switchedon and HasScript(this, "onswitchoff")) {
        do (this, "onswitchoff")
      }
    </changedswitchedon>
  </type>
  <type name="defaultexit">
    <displayverbs type="stringlist">
      <value>Go to</value>
    </displayverbs>
    <visible />
    <scenery type="boolean">false</scenery>
    <locked type="boolean">false</locked>
    <lockmessage>That way is locked.</lockmessage>
    <lookonly type="boolean">false</lookonly>
    <runscript type="boolean">false</runscript>
    <lightstrength type="string"></lightstrength>
    <attr name="grid_length" type="int">1</attr>
    <attr name="grid_render" type="boolean">false</attr>
    <attr name="grid_offset_x" type="int">0</attr>
    <attr name="grid_offset_y" type="int">0</attr>
  </type>
  <type name="direction">
    <displayverbs type="stringlist">
      <value>Go</value>
    </displayverbs>
  </type>
  <type name="compassdirection">
    <inherit name="direction" />
    <prefix type="string"></prefix>
    <suffix type="string"></suffix>
  </type>
  <type name="updowndirection">
    <inherit name="direction" />
    <prefix type="string"></prefix>
    <suffix type="string"></suffix>
  </type>
  <type name="inoutdirection">
    <inherit name="direction" />
    <prefix type="string"></prefix>
    <suffix type="string"></suffix>
  </type>
  <type name="northwestdirection">
    <inherit name="compassdirection" />
    <alias>northwest</alias>
    <alt type="stringlist">
      <value>nw</value>
    </alt>
  </type>
  <type name="northdirection">
    <inherit name="compassdirection" />
    <alias>north</alias>
    <alt type="stringlist">
      <value>n</value>
    </alt>
  </type>
  <type name="northeastdirection">
    <inherit name="compassdirection" />
    <alias>northeast</alias>
    <alt type="stringlist">
      <value>ne</value>
    </alt>
  </type>
  <type name="westdirection">
    <inherit name="compassdirection" />
    <alias>west</alias>
    <alt type="stringlist">
      <value>w</value>
    </alt>
  </type>
  <type name="eastdirection">
    <inherit name="compassdirection" />
    <alias>east</alias>
    <alt type="stringlist">
      <value>e</value>
    </alt>
  </type>
  <type name="southwestdirection">
    <inherit name="compassdirection" />
    <alias>southwest</alias>
    <alt type="stringlist">
      <value>sw</value>
    </alt>
  </type>
  <type name="southdirection">
    <inherit name="compassdirection" />
    <alias>south</alias>
    <alt type="stringlist">
      <value>s</value>
    </alt>
  </type>
  <type name="southeastdirection">
    <inherit name="compassdirection" />
    <alias>southeast</alias>
    <alt type="stringlist">
      <value>se</value>
    </alt>
  </type>
  <type name="updirection">
    <inherit name="updowndirection" />
    <alias>up</alias>
    <alt type="stringlist">
      <value>u</value>
    </alt>
  </type>
  <type name="downdirection">
    <inherit name="updowndirection" />
    <alias>down</alias>
    <alt type="stringlist">
      <value>d</value>
    </alt>
  </type>
  <type name="indirection">
    <inherit name="inoutdirection" />
    <alias>in</alias>
    <alt type="stringlist">
      <value></value>
    </alt>
  </type>
  <type name="outdirection">
    <inherit name="inoutdirection" />
    <alias>out</alias>
    <alt type="stringlist">
      <value>o</value>
    </alt>
  </type>
  <type name="defaultcommand">
    <pattern type="simplepattern"></pattern>
  </type>
  <type name="defaultverb">
    <separator>with; using</separator>
    <multiobjectmenu>With which object?</multiobjectmenu>
    <multiobjectdefault>That doesn't work.</multiobjectdefault>
    <multiobjectmenuempty>There are no objects available to do that with.</multiobjectmenuempty>
    <script type="script"><![CDATA[
      if (not IsDefined("object2")) {
        object2 = null
      }
      switch (TypeOf(object, this.property)) {
        case ("script") {
          if (object2 = null) {
            do (object, this.property)
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("string") {
          if (object2 = null) {
            msg (GetString(object, this.property))
          }
          else {
            msg (this.multiobjectdefault)
          }
        }
        case ("scriptdictionary") {
          if (object2 <> null) {
            HandleMultiVerb (object, this.property, object2, this.multiobjectdefault)
          }
          else {
            objectlist = ListCombine (ScopeReachableInventory(), ScopeReachableNotHeld())
            excludelist = NewObjectList()
            list add (excludelist, game.pov)
            list add (excludelist, object)
            candidates = ListExclude(RemoveSceneryObjects(objectlist), excludelist)
            if (ListCount(candidates) = 0) {
              msg (this.multiobjectmenuempty)
            }
            else {
              game.pov.multiverb = this.property
              game.pov.multiverbobject = object
              game.pov.multiverbobjectdefault = this.multiobjectdefault
              ShowMenu (this.multiobjectmenu, candidates, true) {
                if (result <> null) {
                  HandleMultiVerb (game.pov.multiverbobject, game.pov.multiverb, GetObject(result), game.pov.multiverbobjectdefault)
                  game.pov.multiverb = null
                  game.pov.multiverbobject = null
                  game.pov.multiverbobjectdefault = null
                }
              }
            }
          }
        }
        case ("null") {
          if (this.defaulttext <> null) {
            msg (this.defaulttext)
          }
          else if (this.defaulttemplate <> null) {
            msg (DynamicTemplate(this.defaulttemplate, object))
          }
          else if (this.defaultexpression <> null) {
            params = NewDictionary()
            dictionary add (params, "object", object)
            msg (Eval(this.defaultexpression, params))
          }
          else {
            error ("No verb response defined")
          }
        }
        default {
          error ("No verb response defined")
        }
      }
    ]]></script>
  </type>
  <type name="npc_type">
    <displayverbs type="stringlist">
      <value>Look at</value>
      <value>Speak to</value>
    </displayverbs>
    <not_all />
  </type>
  <type name="plural_npc_type">
    <inherit name="npc_type" />
    <displayverbs type="stringlist">
      <value>Look at</value>
      <value>Speak to</value>
    </displayverbs>
  </type>
  <type name="male">
    <inherit name="npc_type" />
    <gender>he</gender>
    <article>him</article>
    <possessive>his</possessive>
    <wornmodifier>worn</wornmodifier>
  </type>
  <type name="namedmale">
    <inherit name="male" />
    <usedefaultprefix type="boolean">false</usedefaultprefix>
  </type>
  <type name="female">
    <inherit name="npc_type" />
    <displayverbs type="stringlist">
      <value>Look at</value>
      <value>Speak to</value>
    </displayverbs>
    <gender>she</gender>
    <article>her</article>
    <possessive>her</possessive>
    <wornmodifier>worn</wornmodifier>
  </type>
  <type name="namedfemale">
    <inherit name="female" />
    <usedefaultprefix type="boolean">false</usedefaultprefix>
  </type>
  <type name="plural">
    <gender>they</gender>
    <article>them</article>
    <possessive>their</possessive>
    <wornmodifier>worn</wornmodifier>
  </type>
  <type name="maleplural">
    <inherit name="plural_npc_type" />
    <displayverbs type="stringlist">
      <value>Look at</value>
      <value>Speak to</value>
    </displayverbs>
    <gender>they</gender>
    <article>them</article>
    <possessive>their</possessive>
    <wornmodifier>worn</wornmodifier>
  </type>
  <type name="femaleplural">
    <inherit name="plural_npc_type" />
    <displayverbs type="stringlist">
      <value>Look at</value>
      <value>Speak to</value>
    </displayverbs>
    <gender>they</gender>
    <article>them</article>
    <possessive>their</possessive>
    <wornmodifier>worn</wornmodifier>
  </type>
  <type name="openable">
    <open />
    <close />
    <displayverbs type="stringlist">
      <value>Open</value>
      <value>Close</value>
    </displayverbs>
    <inventoryverbs type="stringlist">
      <value>Open</value>
      <value>Close</value>
    </inventoryverbs>
  </type>
  <type name="container_base">
    <container />
  </type>
  <type name="container_closed">
    <inherit name="container_base" />
    <open />
    <close />
    <displayverbs type="stringlist">
      <value>Open</value>
      <value>Close</value>
    </displayverbs>
    <inventoryverbs type="stringlist">
      <value>Open</value>
      <value>Close</value>
    </inventoryverbs>
  </type>
  <type name="container_open">
    <inherit name="container_base" />
    <isopen />
    <open />
    <close />
    <displayverbs type="stringlist">
      <value>Open</value>
      <value>Close</value>
    </displayverbs>
    <inventoryverbs type="stringlist">
      <value>Open</value>
      <value>Close</value>
    </inventoryverbs>
  </type>
  <type name="surface">
    <inherit name="container_base" />
    <isopen />
    <transparent />
    <contentsprefix>on which there is</contentsprefix>
  </type>
  <type name="container">
    <inherit name="container_open" />
    <displayverbs type="stringlist">
      <value>Open</value>
      <value>Close</value>
    </displayverbs>
    <inventoryverbs type="stringlist">
      <value>Open</value>
      <value>Close</value>
    </inventoryverbs>
  </type>
  <type name="container_limited">
    <inherit name="container" />
    <maxobjects type="int">1</maxobjects>
    <maxvolume type="int">100</maxvolume>
    <addscript type="script"><![CDATA[
      activecontainer = this
      correct = true
      while (DoesInherit(activecontainer, "container_base")) {
        if (HasInt(activecontainer, "maxvolume")) {
          if (GetVolume(object, true) + GetVolume(activecontainer, false) > activecontainer.maxvolume) {
            correct = false
            if (HasString(this, "containerfullmessage")) {
              message = this.containerfullmessage
            }
            else {
              message = DynamicTemplate("ContainerFull", this)
            }
          }
        }
        activecontainer = activecontainer.parent
      }
      children = GetDirectChildren(this)
      if (listcount(children) >= this.maxobjects) {
        correct = false
        if (HasString(this, "containermaxobjects")) {
          message = this.containermaxobjects
        }
        else {
          message = DynamicTemplate("MaxObjectsInContainer", this)
        }
      }
      if (correct = false) {
        msg (message)
      }
      else {
        if (HasScript(object, "drop")) {
          params = NewDictionary()
          dictionary add (params, "destination", this)
          do (object, "drop", params)
        }
        else {
          object.parent = this
          msg (Template("Done"))
        }
      }
    ]]></addscript>
    <displayverbs type="stringlist">
      <value>Open</value>
      <value>Close</value>
    </displayverbs>
    <inventoryverbs type="stringlist">
      <value>Open</value>
      <value>Close</value>
    </inventoryverbs>
  </type>
  <type name="container_lockable">
    <locked />
    <nokeymessage>{=WriteVerb(game.pov, "do")} not have the key.</nokeymessage>
    <unlockmessage>Unlocked.</unlockmessage>
    <lockmessage>Locked.</lockmessage>
    <canlockopen type="boolean">false</canlockopen>
    <autoopen />
    <autounlock />
    <openscript type="script">
      if (this.locked) {
        if (this.autounlock and AllKeysAvailable(this)) {
          do (this, "unlock")
          if (not this.isopen) {
            OpenObject (this)
          }
        }
        else {
          msg (DynamicTemplate("LockedObject", this))
        }
      }
      else {
        OpenObject (this)
      }
    </openscript>
    <closescript type="script">
      if (this.locked) {
        msg (DynamicTemplate("LockedObject", this))
      }
      else {
        CloseObject (this)
      }
    </closescript>
    <lock type="script">
      if (this.locked) {
        msg (DynamicTemplate("AlreadyLocked", this))
      }
      else if (this.isopen and not this.canlockopen) {
        msg (DynamicTemplate("CannotLockOpen", this))
      }
      else {
        if (AllKeysAvailable(this)) {
          msg (this.lockmessage)
          this.locked = true
        }
        else {
          msg (this.nokeymessage)
        }
      }
    </lock>
    <unlock type="script">
      if (not this.locked) {
        msg (DynamicTemplate("AlreadyUnlocked", this))
      }
      else {
        if (AllKeysAvailable(this)) {
          msg (this.unlockmessage)
          this.locked = false
          if (this.autoopen and not this.isopen) {
            TryOpenClose (true, this)
          }
        }
        else {
          msg (this.nokeymessage)
        }
      }
    </unlock>
  </type>
  <type name="defaultplayer">
    <inherit name="editor_object" />
    <money type="int">0</money>
  </type>
  <type name="switchable">
    <switchedon type="boolean">false</switchedon>
    <cannotswitchon type="string"></cannotswitchon>
    <turnon type="script">
      if (ListContains(ScopeReachable(), this)) {
        if (this.switchedon) {
          msg (DynamicTemplate("AlreadySwitchedOn", this))
        }
        else if (not this.cannotswitchon = "") {
          msg (this.cannotswitchon)
        }
        else {
          if (HasString(this, "switchonmsg")) {
            msg (this.switchonmsg)
          }
          else {
            msg (DynamicTemplate("SwitchedOn", this))
          }
          this.switchedon = true
        }
      }
      else {
        msg (DynamicTemplate("DefaultTurnOn", this))
      }
    </turnon>
    <turnoff type="script">
      if (ListContains(ScopeReachable(), this)) {
        if (not this.switchedon) {
          msg (DynamicTemplate("AlreadySwitchedOff", this))
        }
        else {
          if (HasString(this, "switchoffmsg")) {
            msg (this.switchoffmsg)
          }
          else {
            msg (DynamicTemplate("SwitchedOff", this))
          }
          this.switchedon = false
        }
      }
      else {
        msg (DynamicTemplate("DefaultTurnOff", this))
      }
    </turnoff>
    <displayverbs type="stringlist">
      <value>Switch on</value>
      <value>Switch off</value>
    </displayverbs>
    <inventoryverbs type="stringlist">
      <value>Switch on</value>
      <value>Switch off</value>
    </inventoryverbs>
  </type>
  <type name="edible">
    <eathealth type="int">0</eathealth>
    <runscript type="boolean">false</runscript>
    <eat type="script">
      if (HasScript(this, "eatscript") and this.runscript) {
        do (this, "eatscript")
      }
      else {
        if (HasString(this, "eatmsg")) {
          msg (this.eatmsg)
        }
        else {
          msg (DynamicTemplate("Eaten", this))
        }
        if (HasInt(game.pov, "health")) {
          game.pov.health = game.pov.health + this.eathealth
        }
        destroy (this.name)
      }
    </eat>
    <displayverbs type="stringlist">
      <value>Eat</value>
    </displayverbs>
    <inventoryverbs type="stringlist">
      <value>Eat</value>
    </inventoryverbs>
  </type>
  <type name="gridborder_path_ew">
    <attr name="grid_bordersides" type="int">10</attr>
  </type>
  <type name="gridborder_path_e">
    <attr name="grid_bordersides" type="int">11</attr>
  </type>
  <type name="gridborder_path_w">
    <attr name="grid_bordersides" type="int">14</attr>
  </type>
  <type name="gridborder_path_ns">
    <attr name="grid_bordersides" type="int">5</attr>
  </type>
  <type name="gridborder_path_n">
    <attr name="grid_bordersides" type="int">7</attr>
  </type>
  <type name="gridborder_path_s">
    <attr name="grid_bordersides" type="int">13</attr>
  </type>
  <type name="wearable">
    <usestandardverblist />
    <worn type="boolean">false</worn>
    <armour type="int">0</armour>
    <attr name="multistate_status" type="int">0</attr>
    <invverbs type="string"></invverbs>
    <wornverbs type="string"></wornverbs>
    <removeable />
    <attr name="wear_layer" type="int">2</attr>
    <wear_adjverbs />
    <wear_slots type="stringlist" />
    <take type="script">
      msg (DynamicTemplate("TakeSuccessful", this))
      this.parent = game.pov
      SetVerbs
    </take>
    <colourmylistalias type="script"><![CDATA[
      if (HasString(this, "alias")) {
        s = CapFirst(this.alias)
      }
      else {
        s = CapFirst(this.name)
      }
      if (HasString(this, "listalias")) {
        s = this.listalias
      }
      this.listalias = "<span style=\"color:blue\">" + s + "</span>"
    ]]></colourmylistalias>
    <inventoryverbs type="stringlist">
      <value>Wear</value>
      <value>Remove</value>
    </inventoryverbs>
  </type>
  <type name="devmode">
    <devmode_active />
    <attr name="devmode_changepov" type="boolean">false</attr>
    <attr name="devmode_changepovpos" type="boolean">false</attr>
    <attr name="devmode_setinitscript" type="boolean">false</attr>
    <devmode_setverbs />
    <devmode_showinfos />
    <devmode_showdebugtable />
    <devmode_ownfontcolour />
    <attr name="devmode_fontcolour">Green</attr>
    <devmode_attributes type="stringdictionary" />
    <devmode_verbs type="stringlist">
      <value>#drop</value>
      <value>#take</value>
      <value>#to</value>
      <value>#open</value>
      <value>#close</value>
      <value>#on</value>
      <value>#off</value>
    </devmode_verbs>
  </type>
  <type name="editor_object">
    <isroom type="boolean">false</isroom>
  </type>
  <type name="editor_room">
    <isroom />
  </type>
  <type name="editor_room_object">
    <isroom />
  </type>
  <function name="GetDefaultPrefix" parameters="obj" type="string"><![CDATA[
    if (Instr("aeiou", LCase(Left(GetDisplayAlias(obj), 1))) > 0) {
      return ("an")
    }
    else {
      return ("a")
    }
  ]]></function>
  <function name="WriteVerb" parameters="obj, verb" type="string">
    result = Conjugate(obj, verb)
    if (not UCase (Left (result, 1)) = LCase (Left (result, 1))) {
      // Don't add a space for 'm, etc.
      result = " " + result
    }
    return (CapFirst(obj.gender) + result)
  </function>
  <function name="Conjugate" parameters="obj, verb" type="string">
    InitConjugation
    gender = LCase(obj.gender)
    if (gender = "he" or gender = "she") {
      gender = "it"
    }
    cmd = GetObject (verb)
    if (not cmd = null and HasString (cmd, "conjugate_"+gender)) {
      return (GetString (cmd, "conjugate_"+gender))
    }
    dict = GetAttribute (game, "conjugations_"+gender)
    if (not dict = null) {
      if (DictionaryContains (dict, verb)) {
        return (DictionaryItem (dict, verb))
      }
      foreach (ending, dict) {
        if (Left (ending, 1) = "@" and EndsWith (verb, Mid (ending, 2))) {
          return (Conjugate (obj, Left (verb, LengthOf(verb) - LengthOf(ending) + 1)) + DictionaryItem (dict, ending))
        }
        else if (Left (ending, 1) = "*" and EndsWith (verb, Mid (ending, 2))) {
          return (Left (verb, LengthOf(verb) - LengthOf(ending) + 1) + DictionaryItem (dict, ending))
        }
      }
    }
    return (verb)
  </function>
  <function name="InitConjugation">
    if (not HasAttribute(game, "conjugations_i")) {
      game.conjugations_i = NewStringDictionary()
      dictionary add (game.conjugations_i, "be", "am")
      dictionary add (game.conjugations_i, "'be", "'m")
      game.conjugations_you = NewStringDictionary()
      dictionary add (game.conjugations_you, "be", "are")
      dictionary add (game.conjugations_you, "'be", "'re")
      game.conjugations_we = NewStringDictionary()
      dictionary add (game.conjugations_we, "be", "are")
      dictionary add (game.conjugations_we, "'be", "'re")
      game.conjugations_they = NewStringDictionary()
      dictionary add (game.conjugations_they, "be", "are")
      dictionary add (game.conjugations_they, "'be", "'re")
      game.conjugations_it = NewStringDictionary()
      dictionary add (game.conjugations_it, "be", "is")
      dictionary add (game.conjugations_it, "have", "has")
      dictionary add (game.conjugations_it, "can", "can")
      dictionary add (game.conjugations_it, "mould", "moulds")
      dictionary add (game.conjugations_it, "*ould", "ould")
      dictionary add (game.conjugations_it, "must", "must")
      dictionary add (game.conjugations_it, "can't", "can't")
      dictionary add (game.conjugations_it, "won't", "won't")
      dictionary add (game.conjugations_it, "cannot", "cannot")
      dictionary add (game.conjugations_it, "@n't", "n't")
      dictionary add (game.conjugations_it, "'ve", "'s")
      dictionary add (game.conjugations_it, "'be", "'s")
      dictionary add (game.conjugations_it, "*ay", "ays")
      dictionary add (game.conjugations_it, "*oy", "oys")
      dictionary add (game.conjugations_it, "*ey", "eys")
      dictionary add (game.conjugations_it, "*y", "ies")
      dictionary add (game.conjugations_it, "*ss", "sses")
      dictionary add (game.conjugations_it, "*s", "sses")
      dictionary add (game.conjugations_it, "*sh", "shes")
      dictionary add (game.conjugations_it, "*ch", "ches")
      dictionary add (game.conjugations_it, "*o", "oes")
      dictionary add (game.conjugations_it, "*x", "xes")
      dictionary add (game.conjugations_it, "*z", "zes")
      dictionary add (game.conjugations_it, "*", "s")
    }
  </function>
  <function name="Possessive" parameters="possessive, object" type="string">
    return (possessive + " " + GetDisplayAlias(object))
  </function>
  <function name="ToWords" parameters="number" type="string"><![CDATA[
    if (not TypeOf(number) = "int") {
      error ("ToWords can only handle ints")
    }
    number_units = Split("zero;one;two;three;four;five;six;seven;eight;nine;ten;eleven;twelve;thirteen;fourteen;fifteen;sixteen;seventeen;eighteen;nineteen;twenty", ";")
    number_tens = Split("twenty;thirty;forty;fifty;sixty;seventy;eighty;ninety", ";")
    s = ""
    if (number < 0) {
      s = "minus "
      number = -number
    }
    if (number < 2000) {
      hundreds = number / 100
      number = number % 100
      if (hundreds > 0) {
        s = s + StringListItem(number_units, hundreds) + " hundred "
        if (number > 0) {
          s = s + "and "
        }
      }
      if (number < 20) {
        if (not number = 0 or s = "") {
          s = s + StringListItem(number_units, number)
        }
      }
      else {
        units = number % 10
        tens = (number / 10) % 10
        s = s + StringListItem(number_tens, tens - 2)
        if (not units = 0) {
          s = s + StringListItem(number_units, units)
        }
      }
    }
    else {
      s = ToString(number)
    }
    return (Trim(s))
  ]]></function>
  <function name="GetDefiniteName" parameters="obj" type="string">
    result = GetDisplayAlias(obj)
    if (not DoesInherit(obj, "namedmale") and not DoesInherit(obj, "namedfemale") and not result = "me" and not result = "you") {
      result = "the " + result
    }
    return (result)
  </function>
  <function name="ListObjectContents" parameters="object"><![CDATA[
    if ((GetBoolean(object, "isopen") or GetBoolean(object, "transparent")) and GetBoolean(object, "listchildren")) {
      if (GetBoolean(object, "hidechildren")) {
        object.hidechildren = false
      }
      if (HasString(object, "listchildrenprefix")) {
        listprefix = object.listchildrenprefix
      }
      else {
        listprefix = DynamicTemplate("ObjectContains", object)
      }
      list = FormatObjectList(listprefix, object, Template("And"), ".")
      if (list <> "") {
        msg (list)
      }
    }
  ]]></function>
  <function name="DoTake" parameters="object, ismultiple"><![CDATA[
    prefix = ""
    if (ismultiple) {
      prefix = GetDisplayAlias(object) + ": "
    }
    if (object.parent = game.pov) {
      msg (prefix + DynamicTemplate("AlreadyTaken", object))
    }
    else if (not ListContains(ScopeReachable(), object)) {
      msg (BlockingMessage(object, prefix))
    }
    else if (not TestTakeGlobal(object, prefix)) {
      // Do nothing, already handled
    }
    else if (not CheckLimits(object, prefix)) {
      // Do nothing, already handled
    }
    else {
      found = true
      takemsg = object.takemsg
      switch (TypeOf(object, "take")) {
        case ("script") {
          if (ismultiple) {
            OutputTextNoBr (prefix)
          }
          do (object, "take")
          takemsg = ""
        }
        case ("boolean") {
          if (object.take = true) {
            object.parent = game.pov
            if (takemsg = null) {
              takemsg = DynamicTemplate("TakeSuccessful", object)
            }
          }
          else {
            found = false
          }
        }
        case ("string") {
          object.parent = game.pov
          takemsg = object.take
        }
        default {
          found = false
        }
      }
      if (not found and takemsg = null) {
        takemsg = DynamicTemplate("TakeUnsuccessful", object)
      }
      if (LengthOf(takemsg) > 0) {
        msg (prefix + takemsg)
      }
      if (HasScript(object, "ontake")) {
        do (object, "ontake")
      }
      if (found and GetBoolean (object, "scenery") and object.parent = game.pov) {
        object.scenery = false
      }
    }
  ]]></function>
  <function name="CheckLimits" parameters="object, prefix" type="boolean"><![CDATA[
    volume = 0
    foreach (obj, GetAllChildObjects(game.pov)) {
      if (HasInt(obj, "volume")) {
        volume = volume + obj.volume
      }
    }
    if (not Contains(game.pov, object)) {
      volume = volume + GetVolume(object,true)
    }
    if (HasInt(game.pov, "maxvolume")) {
      if (volume > game.pov.maxvolume) {
        if (HasString(game.pov, "containerfullmessage")) {
          msg (prefix + game.pov.containerfullmessage)
        }
        else {
          msg (prefix + DynamicTemplate("FullInventory", object))
        }
        return (false)
      }
    }
    children = GetDirectChildren(game.pov)
    if (HasInt(game.pov, "maxobjects")) {
      if (game.pov.maxobjects > 0) {
        if (ListCount(children) >= game.pov.maxobjects) {
          if (HasString(game.pov, "containermaxobjects")) {
            msg (prefix + game.pov.containermaxobjects)
          }
          else {
            msg (prefix + DynamicTemplate("MaxObjectsInInventory", object))
          }
        }
      }
    }
    return (true)
  ]]></function>
  <function name="TestTakeGlobal" parameters="object, prefix" type="boolean">
    if (HasString(game.pov, "notallowedtotake")) {
      msg (game.pov.notallowedtotake)
      return (false)
    }
    else {
      return (true)
    }
  </function>
  <function name="DoDrop" parameters="object, ismultiple"><![CDATA[
    prefix = ""
    oldparent = object.parent
    if (ismultiple) {
      prefix = GetDisplayAlias(object) + ": "
    }
    if (not ListContains(ScopeInventory(), object)) {
      msg (prefix + DynamicTemplate("NotCarrying", object))
    }
    else if (not ListContains(ScopeReachable(), object)) {
      msg (BlockingMessage(object, prefix))
    }
    else if (not TestDropGlobal(object, prefix)) {
      // Do nothing, already handled
    }
    else {
      found = true
      dropmsg = object.dropmsg
      if (HasObject(game.pov.parent, "dropdestination")) {
        destination = game.pov.parent.dropdestination
      }
      else {
        destination = game.pov.parent
      }
      switch (TypeOf(object, "drop")) {
        case ("script") {
          if (ismultiple) {
            OutputTextNoBr (prefix)
          }
          d = NewDictionary()
          dictionary add (d, "destination", destination)
          do (object, "drop", d)
          dropmsg = ""
        }
        case ("boolean") {
          if (object.drop = true) {
            object.parent = destination
            if (dropmsg = null) {
              dropmsg = DynamicTemplate("DropSuccessful", object)
            }
          }
          else {
            found = false
          }
        }
        case ("string") {
          object.parent = game.pov.parent
          dropmsg = object.drop
        }
        default {
          found = false
        }
      }
      if (not found and dropmsg = null) {
        dropmsg = DynamicTemplate("DropUnsuccessful", object)
      }
      if (LengthOf(dropmsg) > 0) {
        msg (prefix + dropmsg)
      }
      if (HasScript(object, "ondrop")) {
        do (object, "ondrop", QuickParams("successful", not oldparent = object.parent))
      }
    }
  ]]></function>
  <function name="TestDropGlobal" parameters="object, prefix" type="boolean">
    if (HasString(game.pov, "notallowedtodrop")) {
      msg (game.pov.notallowedtodrop)
      return (false)
    }
    else {
      return (true)
    }
  </function>
  <function name="CreateUseMenuList" parameters="object" type="objectlist">
    objectlist = NewObjectList()
    objectlist = ScopeReachableInventory()
    objectlist = ListCombine (objectlist, ScopeReachableNotHeld())
    excludelist = NewObjectList()
    list add (excludelist, game.pov)
    list add (excludelist, object)
    candidates = NewObjectList()
    candidates = ListExclude(RemoveSceneryObjects(objectlist), excludelist)
    return (candidates)
  </function>
  <function name="TestExitGlobal" parameters="exit" type="boolean">
    if (HasString(game.pov, "notallowedtoexit")) {
      msg (game.pov.notallowedtoexit)
      return (false)
    }
    else {
      return (true)
    }
  </function>
  <function name="TryOpenClose" parameters="doopen, object">
    if (doopen) {
      action = "open"
      scriptaction = "openscript"
    }
    else {
      action = "close"
      scriptaction = "closescript"
    }
    if (not ListContains(ScopeReachable(), object)) {
      msg (BlockingMessage(object, ""))
    }
    else {
      found = false
      if (GetBoolean(object, action)) {
        if (doopen) {
          if (object.isopen) {
            msg (DynamicTemplate("AlreadyOpen", object))
          }
          else {
            if (HasScript(object, scriptaction)) {
              do (object, scriptaction)
            }
            else {
              OpenObject (object)
            }
          }
        }
        else {
          if (not object.isopen) {
            msg (DynamicTemplate("AlreadyClosed", object))
          }
          else {
            if (HasScript(object, scriptaction)) {
              do (object, scriptaction)
            }
            else {
              CloseObject (object)
            }
          }
        }
      }
      else {
        if (doopen) {
          msg (DynamicTemplate("CantOpen", object))
        }
        else {
          msg (DynamicTemplate("CantClose", object))
        }
      }
    }
  </function>
  <function name="OpenObject" parameters="object">
    if (HasString(object, "openmsg")) {
      msg (object.openmsg)
    }
    else {
      msg (DynamicTemplate("OpenSuccessful", object))
    }
    object.isopen = true
    ListObjectContents (object)
  </function>
  <function name="CloseObject" parameters="object">
    if (HasString(object, "closemsg")) {
      msg (object.closemsg)
    }
    else {
      msg (DynamicTemplate("CloseSuccessful", object))
    }
    object.isopen = false
  </function>
  <function name="CreateGiveMenuList" parameters="object" type="objectlist">
    objectlist = NewObjectList()
    objectlist = ScopeReachableInventory()
    objectlist = ListCombine (objectlist, ScopeReachableNotHeld())
    excludelist = NewObjectList()
    list add (excludelist, game.pov)
    list add (excludelist, object)
    candidates = NewObjectList()
    candidates = ListExclude(RemoveSceneryObjects(objectlist), excludelist)
    return (candidates)
  </function>
  <function name="HandleGiveTo" parameters="object1, object2">
    handled = false
    if (not TestDropGlobal(object1, "")) {
      handled = true
    }
    else if (HasString(object2, "give")) {
      msg (object2.give)
      handled = true
    }
    else if (TypeOf(object2, "give") = "scriptdictionary") {
      if (DictionaryContains(object2.give, object1.name)) {
        parameters = NewObjectDictionary()
        dictionary add (parameters, "this", object2)
        dictionary add (parameters, "object", object1)
        invoke (ScriptDictionaryItem(object2.give, object1.name), parameters)
        handled = true
      }
      if (not handled) {
        if (HasScript(object2, "giveanything")) {
          // TO DO: Would be better to use a delegate for giveanything, but need to implement Editor support first
          parameters = NewObjectDictionary()
          dictionary add (parameters, "object", object1)
          do (object2, "giveanything", parameters)
          handled = true
        }
      }
    }
    if (not handled) {
      if (HasString(object1, "giveto")) {
        msg (object1.giveto)
        handled = true
      }
      else if (TypeOf(object1, "giveto") = "scriptdictionary") {
        if (DictionaryContains(object1.giveto, object2.name)) {
          parameters = NewObjectDictionary()
          dictionary add (parameters, "this", object1)
          dictionary add (parameters, "object", object2)
          invoke (ScriptDictionaryItem(object1.giveto, object2.name), parameters)
          handled = true
        }
        else {
          if (HasScript(object1, "givetoanything")) {
            // TO DO: Would be better to use a delegate for givetoanything, but need to implement Editor support first
            parameters = NewObjectDictionary()
            dictionary add (parameters, "object", object2)
            do (object1, "givetoanything", parameters)
            handled = true
          }
        }
      }
    }
    if (not handled) {
      msg (DynamicTemplate("DefaultGive", object2, object1))
    }
  </function>
  <function name="HandleUseOn" parameters="object1, object2">
    handled = false
    if (HasString(object2, "useon")) {
      msg (object2.useon)
      handled = true
    }
    else if (TypeOf(object2, "useon") = "scriptdictionary") {
      if (DictionaryContains(object2.useon, object1.name)) {
        parameters = NewObjectDictionary()
        dictionary add (parameters, "this", object2)
        dictionary add (parameters, "object", object1)
        invoke (ScriptDictionaryItem(object2.useon, object1.name), parameters)
        handled = true
      }
      else {
        if (HasScript(object2, "useanything")) {
          // TO DO: Would be better to use a delegate for useanything, but need to implement Editor support first
          parameters = NewObjectDictionary()
          dictionary add (parameters, "object", object1)
          do (object2, "useanything", parameters)
          handled = true
        }
      }
    }
    if (not handled) {
      if (HasString(object1, "selfuseon")) {
        msg (object1.selfuseon)
        handled = true
      }
      else if (TypeOf(object1, "selfuseon") = "scriptdictionary") {
        if (DictionaryContains(object1.selfuseon, object2.name)) {
          parameters = NewObjectDictionary()
          dictionary add (parameters, "this", object1)
          dictionary add (parameters, "object", object2)
          invoke (ScriptDictionaryItem(object1.selfuseon, object2.name), parameters)
          handled = true
        }
        else {
          if (HasScript(object1, "selfuseanything")) {
            // TO DO: Would be better to use a delegate for selfuseanything, but need to implement Editor support first
            parameters = NewObjectDictionary()
            dictionary add (parameters, "object", object2)
            do (object1, "selfuseanything", parameters)
            handled = true
          }
        }
      }
    }
    if (not handled) {
      msg (DynamicTemplate("DefaultUseOn", object2, object1))
    }
  </function>
  <function name="DoAskTell" parameters="object, text, property, defaultscript, defaulttemplate"><![CDATA[
    handled = false
    maxstrength = 0
    match = null
    text = LCase(text)
    if (TypeOf(object, property) = "scriptdictionary") {
      dictionary = GetAttribute(object, property)
      foreach (keywords, dictionary) {
        strength = GetKeywordsMatchStrength(LCase(keywords), text)
        if (strength >= maxstrength and strength>0) {
          match = ScriptDictionaryItem(dictionary, keywords)
          maxstrength = strength
        }
      }
      if (match <> null) {
        parameters = NewObjectDictionary()
        dictionary add (parameters, "this", object)
        invoke (match, parameters)
        handled = true
      }
    }
    if (not handled) {
      if (HasScript(object, defaultscript)) {
        d = NewDictionary()
        dictionary add (d, "text", text)
        do (object, defaultscript, d)
      }
      else {
        msg (DynamicTemplate(defaulttemplate, object))
      }
    }
  ]]></function>
  <function name="GetKeywordsMatchStrength" parameters="keywords, input" type="int">
    // Keywords is the subject. We split it into individual words, and then see how well
    // the words in the input match the keywords.
    keywordlist = Split(keywords, " ")
    inputlist = Split(input, " ")
    strength = 0
    foreach (word, inputlist) {
      foreach (keyword, keywordlist) {
        if (StartsWith(word, keyword)) {
          strength = strength + LengthOf(keyword)
        }
      }
    }
    return (strength)
  </function>
  <function name="BlockingMessage" parameters="blocked, prefix" type="string">
    obj = GetBlockingObject(blocked)
    if (HasString(obj, "blockingmessage")) {
      return (obj.blockingmessage)
    }
    else {
      return (prefix + DynamicTemplate("ObjectNotOpen", obj))
    }
  </function>
  <function name="RandomChance" parameters="percentile" type="boolean"><![CDATA[
    return (GetRandomInt(1,100) <= percentile)
  ]]></function>
  <function name="SetObjectFlagOn" parameters="object, flag">
    set (object, flag, true)
  </function>
  <function name="SetObjectFlagOff" parameters="object, flag">
    set (object, flag, false)
  </function>
  <function name="IncreaseObjectCounter" parameters="object, counter">
    if (not HasInt(object, counter)) {
      set (object, counter, 0)
    }
    set (object, counter, GetInt(object, counter) + 1)
  </function>
  <function name="DecreaseObjectCounter" parameters="object, counter">
    if (not HasInt(object, counter)) {
      set (object, counter, 0)
    }
    set (object, counter, GetInt(object, counter) - 1)
  </function>
  <function name="IsSwitchedOn" parameters="object" type="boolean">
    return (GetBoolean(object, "switchedon"))
  </function>
  <function name="AddToInventory" parameters="object">
    object.parent = game.pov
  </function>
  <function name="MoveObject" parameters="object, parent">
    object.parent = parent
  </function>
  <function name="MovePlayer" parameters="loc">
    game.pov.parent = loc
  </function>
  <function name="MoveObjectHere" parameters="object">
    object.parent = game.pov.parent
  </function>
  <function name="RemoveObject" parameters="object">
    object.parent = null
  </function>
  <function name="MakeObjectVisible" parameters="object">
    object.visible = true
  </function>
  <function name="MakeObjectInvisible" parameters="object">
    object.visible = false
  </function>
  <function name="MakeExitVisible" parameters="object">
    object.visible = true
  </function>
  <function name="MakeExitInvisible" parameters="object">
    object.visible = false
  </function>
  <function name="HelperOpenObject" parameters="object">
    object.isopen = true
  </function>
  <function name="HelperCloseObject" parameters="object">
    object.isopen = false
  </function>
  <function name="CloneObject" parameters="object" type="object">
    newobject = ShallowClone(object)
    if (not HasString(object, "alias")) {
      newobject.alias = object.name
    }
    if (not HasAttribute(object, "prototype")) {
      newobject.prototype = object
    }
    foreach (o, GetDirectChildren(object)) {
      o2 = CloneObject (o)
      MoveObject (o2, newobject)
    }
    return (newobject)
  </function>
  <function name="CloneObjectAndMove" parameters="object, newparent" type="object">
    newobject = CloneObject(object)
    newobject.parent = newparent
    return (newobject)
  </function>
  <function name="CloneObjectAndInitialise" parameters="object" type="object">
    newobject = CloneObject(object)
    if (HasScript(newobject, "_initialise_")) {
      do (newobject, "_initialise_")
    }
    return (newobject)
  </function>
  <function name="CloneObjectAndMoveHere" parameters="object" type="object">
    newobject = CloneObject(object)
    newobject.parent = game.pov.parent
    return (newobject)
  </function>
  <function name="GetClone" parameters="prototype, parent" type="object">
    if (not IsDefined("parent")) {
      parent = game.pov
    }
    foreach (obj, GetDirectChildren(parent)) {
      if (obj.prototype = prototype) {
        return (obj)
      }
    }
    return (null)
  </function>
  <function name="LockExit" parameters="exit">
    exit.locked = true
  </function>
  <function name="UnlockExit" parameters="exit">
    exit.locked = false
  </function>
  <function name="SwitchOn" parameters="object">
    object.switchedon = true
  </function>
  <function name="SwitchOff" parameters="object">
    object.switchedon = false
  </function>
  <function name="SetDark" parameters="object">
    object.dark = true
  </function>
  <function name="SetLight" parameters="object">
    object.dark = false
  </function>
  <function name="SetObjectLightstrength" parameters="object, strength">
    if (LengthOf(strength) = 0) {
      object.lightsource = false
    }
    else {
      object.lightsource = true
    }
    object.lightstrength = strength
  </function>
  <function name="SetExitLightstrength" parameters="exit, strength">
    if (LengthOf(strength) = 0) {
      exit.lightsource = false
    }
    else {
      exit.lightsource = true
    }
    exit.lightstrength = strength
  </function>
  <function name="ChangePOV" parameters="object"><![CDATA[
    if (not HasObject(object, "parent")) {
      error ("ChangePOV cannot change player to object with no parent.")
    }
    if (game.pov <> object) {
      game.pov = object
      if (game.gridmap) {
        JS.Grid_ClearAllLayers ()
        Grid_Redraw
      }
      OnEnterRoom (null)
    }
  ]]></function>
  <function name="RequestSave">
    // Deprecated
    request (RequestSave, "")
  </function>
  <function name="RequestSpeak" parameters="s">
    // Deprecated
    request (Speak, s)
  </function>
  <function name="ShowMenu" parameters="caption, options, allowCancel, callback"><![CDATA[
    outputsection = StartNewOutputSection()
    msg (caption)
    count = 0
    game.menuoptionskeys = NewStringList()
    foreach (option, options) {
      count = count + 1
      if (TypeOf(options) = "stringdictionary") {
        optionText = StringDictionaryItem(options, option)
        optiontag = option
        style = GetCurrentLinkTextFormat()
        list add (game.menuoptionskeys, option)
      }
      else if (TypeOf(option) = "string") {
        optionText = option
        optiontag = option
        style = GetCurrentLinkTextFormat()
        list add (game.menuoptionskeys, option)
      }
      else if (TypeOf(option) = "object") {
        optionText = GetDisplayAlias(option)
        optiontag = option.name
        colour = ""
        if (HasString(option, "linkcolour") and GetUIOption("UseGameColours") = "true") {
          colour = option.linkcolour
        }
        else {
          colour = GetLinkTextColour()
        }
        style = GetCurrentTextFormat(colour)
        list add (game.menuoptionskeys, option.name)
      }
      else {
        error ("ShowMenu cannot handle a " + TypeOf(option))
      }
      msg (count + ": <a class=\"cmdlink\" style=\"" + style + "\" onclick=\"ASLEvent('ShowMenuResponse','" + EscapeQuotes(optiontag) + "')\">" + optionText + "</a>")
    }
    EndOutputSection (outputsection)
    game.menuoptions = options
    game.menuallowcancel = allowCancel
    game.menucallback = callback
    game.menuoutputsection = outputsection
  ]]></function>
  <function name="ShowMenuResponse" parameters="option"><![CDATA[
    if (game.menucallback = null) {
      error ("Unexpected menu response")
    }
    else {
      parameters = NewStringDictionary()
      dictionary add (parameters, "result", UnescapeQuotes(option))
      script = game.menucallback
      if (GetBoolean (game, "donotclearmenus")) {
        DisableMenu
      }
      else {
        ClearMenu
      }
      if (not GetBoolean(game, "disambiguating")) {
        game.runturnscripts = true
      }
      if (GetBoolean (game, "showmenuresponses")) {
        if (GetBoolean (game, "disambiguating")) {
          obj = GetObject (option)
          if (obj <> null) {
            option = GetDisplayAlias(obj)
          }
        }
        msg (Template("ShowMenuResponsePrompt") + option)
      }
      game.disambiguating = false
      invoke (script, parameters)
      FinishTurn
    }
  ]]></function>
  <function name="DisableMenu">
    DisableMenuOutputSection (game.menuoutputsection)
    game.menuoutputsection = null
    game.menuoptions = null
    game.menucallback = null
  </function>
  <function name="DisableMenuOutputSection" parameters="section">
    JS.disableMenuOutputSection (section)
  </function>
  <function name="EscapeQuotes" parameters="s" type="string">
    s = Replace(s, "\"", "@@@doublequote@@@")
    s = Replace(s, "\'", "@@@singlequote@@@")
    return (s)
  </function>
  <function name="UnescapeQuotes" parameters="s" type="string">
    s = Replace(s, "@@@doublequote@@@", "\"")
    s = Replace(s, "@@@singlequote@@@", "\'")
    return (s)
  </function>
  <function name="JSSafe" parameters="s" type="string"><![CDATA[
    s = Replace(s, "\"", "")
    s = Replace(s, "\'", "")
    s = Replace(s, " ", "")
    s = Replace(s, ".", "")
    s = Replace(s, ",", "")
    s = Replace(s, "!", "")
    s = Replace(s, "?", "")
    s = Replace(s, "-", "")
    s = Replace(s, "/", "")
    s = Replace(s, "(", "")
    s = Replace(s, ")", "")
    s = Replace(s, "$", "")
    s = Replace(s, "%", "")
    s = Replace(s, "&", "")
    s = Replace(s, "*", "")
    s = Replace(s, "@", "")
    return (s)
  ]]></function>
  <function name="HandleMenuTextResponse" parameters="input" type="boolean"><![CDATA[
    handled = false
    if (IsInt(input)) {
      number = ToInt(input)
      if (number > 0 and number <= ListCount(game.menuoptionskeys)) {
        handled = true
        if (not GetBoolean(game, "notranscript") and GetBoolean(game, "savetranscript")) {
          JS.SaveTranscript ("<span><br/>> " + SafeXML(input) + "<br/></span>")
        }
        ShowMenuResponse (StringListItem(game.menuoptionskeys, number - 1))
      }
    }
    return (handled)
  ]]></function>
  <function name="ClearMenu">
    HideOutputSection (game.menuoutputsection)
    game.menuoutputsection = null
    game.menuoptions = null
    game.menucallback = null
  </function>
  <function name="StartNewOutputSection" type="string">
    if (not HasInt(game, "lastoutputsection")) {
      game.lastoutputsection = 0
    }
    game.lastoutputsection = game.lastoutputsection + 1
    name = "section" + game.lastoutputsection
    JS.StartOutputSection (name)
    return (name)
  </function>
  <function name="EndOutputSection" parameters="name">
    JS.EndOutputSection (name)
  </function>
  <function name="HideOutputSection" parameters="name">
    JS.HideOutputSection (name)
  </function>
  <function name="StartTurnOutputSection">
    if (HasString(game, "currentturnoutputsection")) {
      game.lastturnoutputsection = game.currentturnoutputsection
      EndOutputSection (game.currentturnoutputsection)
    }
    game.currentturnoutputsection = StartNewOutputSection()
  </function>
  <function name="HidePreviousTurnOutput">
    if (HasString(game, "lastturnoutputsection")) {
      HideOutputSection (game.lastturnoutputsection)
    }
  </function>
  <function name="Ask" parameters="question, callback">
    options = NewStringList()
    list add (options, "Yes")
    list add (options, "No")
    game.askcallback = callback
    ShowMenu (question, options, false) {
      parameters = NewDictionary()
      if (result = "Yes") {
        boolresult = true
      }
      else {
        boolresult = false
      }
      dictionary add (parameters, "result", boolresult)
      callback = game.askcallback
      game.askcallback = null
      invoke (callback, parameters)
    }
  </function>
  <function name="AllKeysAvailable" parameters="object" type="boolean">
    if (HasObject(object, "key")) {
      if (not HasInt(object,"keycount")) {
        object.keycount = 1
        object.key1 = object.key
      }
      if (not HasObject(object, "key1")) {
        object.key1 = object.key
      }
    }
    for (x, 1, object.keycount) {
      keyname = "key" + ToString(x)
      if (HasObject(object, keyname)) {
        if (not ListContains(ScopeInventory(), GetAttribute(object, keyname))) {
          return (false)
        }
      }
    }
    return (true)
  </function>
  <function name="CreateBiExits" parameters="dir, from, to">
    create exit (dir, from, to)
    create exit (ReverseDirection(dir), to, from)
  </function>
  <function name="Equal" parameters="value1, value2" type="boolean">
    if (not TypeOf(value1) = TypeOf(value2)) {
      return (false)
    }
    if (not value1 = value2) {
      return (false)
    }
    return (true)
  </function>
  <function name="ReverseDirection" parameters="dir" type="string">
    list1 = Split("north;northeast;east;southeast;south;southwest;west;northwest;up;down;in;out", ";")
    list2 = Split("south;southwest;west;northwest;north;northeast;east;southeast;down;up;out;in", ";")
    n = IndexOf(list1, dir)
    if (not n = -1) {
      return (StringListItem(list2, n))
    }
    return (dir)
  </function>
  <function name="PadString" parameters="str, n, pad" type="string"><![CDATA[
    s = ""
    str = "" + str
    pad = "" + pad
    step = LengthOf(pad)
    if (step = 0) {
      error ("Zero length pad in PadString")
    }
    if (pad = " ") {
      pad = "&nbsp;"
    }
    for (i, 1, n - LengthOf(str), step) {
      s = s + pad
    }
    return (s + str)
  ]]></function>
  <function name="Decimalise" parameters="n, places" type="string"><![CDATA[
    negative = (n < 0)
    n = abs(n)
    if (places = 0) {
      return ("" + n)
    }
    factor = pow (10, places)
    pounds = floor(n / factor)
    pennies = n % factor
    result = pounds + "." + PadString(pennies, places, 0)
    if (negative) {
      result = "-" + result
    }
    return (result)
  ]]></function>
  <function name="DisplayNumber" parameters="n, control" type="string"><![CDATA[
    n = abs(n)
    regex = "^(?<before>\\D*)(?<padding>\\d+)(?<sep>\\D)(?<places>\\d*)(?<after>\\D*)$"
    if (not IsRegexMatch(regex, control, "DisplayNumber")) {
      error ("Unexpected format in DisplayNumber (" + control + "). Should be a number, followed by a single character separator, followed by a number.")
    }
    options = Populate(regex, control, "DisplayNumber")
    places = ToInt(StringDictionaryItem(options, "places"))
    padding = ToInt(StringDictionaryItem(options, "padding"))
    if (places > 0) {
      padding = padding + 1 + places
    }
    decimal = Replace(Decimalise(n, places), ".", StringDictionaryItem(options, "sep"))
    return (StringDictionaryItem(options, "before") + PadString(decimal, padding, 0) + StringDictionaryItem(options, "after"))
  ]]></function>
  <function name="DisplayMoney" parameters="n" type="string"><![CDATA[
    // Returns the given number formatted according to game.moneyformat
    if (not HasString(game, "moneyformat")) {
      error ("No format for money set in game.moneyformat.")
    }
    ary = Split(game.moneyformat, "!")
    if (ListCount(ary) = 2) {
      return (Replace(game.moneyformat, "!", "" + n))
    }
    else if (ListCount(ary) = 3) {
      negative = (n < 0)
      n = abs(n)
      options = StringListItem(ary, 1)
      showsign = StartsWith(options, "+")
      if (showsign) {
        options = Mid(options, 2)
      }
      number = DisplayNumber(n, options)
      if (negative) {
        number = "-" + number
      }
      else if (not n = 0 and showsign) {
        number = "+" + number
      }
      return (StringListItem(ary, 0) + number + StringListItem(ary, 2))
    }
    else if (ListCount(ary) = 4) {
      if (n < 0) {
        options = StringListItem(ary, 2)
      }
      else {
        options = StringListItem(ary, 1)
      }
      number = DisplayNumber(n, options)
      return (StringListItem(ary, 0) + number + StringListItem(ary, 3))
    }
    else {
      error ("game.moneyformat expected to have either 1, 2 or 3 exclamation marks.")
    }
  ]]></function>
  <function name="IndexOf" parameters="lst, item" type="int">
    for (i, 0, ListCount(lst) - 1) {
      x = ListItem(lst, i)
      if (x = item) {
        return (i)
      }
    }
    return (-1)
  </function>
  <function name="ObjectListToStringList" parameters="list, att" type="stringlist">
    l = NewStringList()
    foreach (o, list) {
      if (HasString(o, att)) {
        list add (l, GetString(o, att))
      }
    }
    return (l)
  </function>
  <function name="FilterByType" parameters="lst, t" type="objectlist">
    l = NewObjectList()
    foreach (o, lst) {
      if (DoesInherit(o, t)) {
        list add (l, o)
      }
    }
    return (l)
  </function>
  <function name="FilterByAttribute" parameters="lst, name, value" type="objectlist">
    if (not IsDefined("value")) {
      return (FilterByNotAttribute (lst, name, null))
    }
    l = NewObjectList()
    foreach (o, lst) {
      val = GetAttribute(o, name)
      if (Equal(val, value)) {
        list add (l, o)
      }
    }
    return (l)
  </function>
  <function name="FilterByNotAttribute" parameters="lst, name, value" type="objectlist">
    if (not IsDefined("value")) {
      return (FilterByAttribute (lst, name, null))
    }
    l = NewObjectList()
    foreach (o, lst) {
      val = GetAttribute(o, name)
      if (not Equal(val, value)) {
        list add (l, o)
      }
    }
    return (l)
  </function>
  <function name="ListCompact" parameters="lst" type="list">
    l = NewList()
    foreach (o, lst) {
      if (not Equal(o, null)) {
        if (IndexOf(l, o) = -1) {
          list add (l, o)
        }
      }
    }
    return (l)
  </function>
  <function name="ObjectListCompact" parameters="lst" type="objectlist">
    l = NewObjectList()
    foreach (o, lst) {
      if (not Equal(o, null)) {
        if (IndexOf(l, o) = -1) {
          list add (l, o)
        }
      }
    }
    return (l)
  </function>
  <function name="AllRooms" type="objectlist">
    return (FilterByAttribute(AllObjects(),"isroom",true))
  </function>
  <function name="DictionaryAdd" parameters="dict, key, val">
    if (dict = null or TypeOf(dict)="object") {
      error ("DictionaryAdd:  Dictionary does not exist!")
    }
    if (DictionaryContains(dict, key)) {
      dictionary remove (dict, key)
    }
    dictionary add (dict, key, val)
  </function>
  <function name="DictionaryRemove" parameters="dict, key">
    if (dict = null or TypeOf(dict)="object") {
      error ("DictionaryRemove:  Dictionary does not exist!")
    }
    if (DictionaryContains(dict, key)) {
      dictionary remove (dict, key)
    }
  </function>
  <function name="DbgLog" parameters="txt">
    if (GetBoolean(game,"debugging")) {
      Log ("DEBUGGING:  "+txt)
    }
  </function>
  <function name="DbgMsg" parameters="txt"><![CDATA[
    if (GetBoolean(game,"debugging")) {
      msg ("<br/><p style='color:blue;font-weight:bold;'>DEBUGGING:  "+txt+"</p><br/>")
    }
  ]]></function>
  <function name="DisableHtmlLog">
    game.nohtmllog = true
  </function>
  <function name="QuickParams" parameters="key1, value1, key2, value2, key3, value3" type="dictionary">
    d = NewDictionary()
    dictionary add (d, key1, value1)
    if (IsDefined("key2")) {
      dictionary add (d, key2, value2)
    }
    if (IsDefined("key3")) {
      dictionary add (d, key3, value3)
    }
    return (d)
  </function>
  <function name="InitiateTranscript" parameters="s"><![CDATA[
    filename = s
    game.transcriptname = game.gamename
    if (not filename = "") {
      JS.eval ("transcriptName = '" + filename + "';")
      game.transcriptname = filename
    }
    msg ("> " + game.transcriptname)
    EnableTranscript
  ]]></function>
  <function name="EnableTranscript"><![CDATA[
    if (GetBoolean (game, "notranscript")) {
      KillTranscript
    }
    else {
      if (not HasAttribute (game, "transcriptname")) {
        game.transcriptname = game.gamename
      }
      game.savetranscript = true
      JS.enableTranscript (game.transcriptname)
      msg ("<br/>" + DynamicTemplate("TranscriptEnabledMessage"))
      JS.printTranscriptDateAndTime ()
    }
  ]]></function>
  <function name="DisableTranscript">
    game.savetranscript = false
    JS.disableTranscript ()
  </function>
  <function name="KillTranscript">
    game.notranscript = true
    JS.killTranscript ()
    DisableTranscript
  </function>
  <function name="UpdateTranscriptString" parameters="data">
    if (not HasAttribute(game,"transcriptstring")) {
      game.transcriptstring = ""
    }
    game.transcriptstring = game.transcriptstring + data
  </function>
  <function name="HandleCommand" parameters="command, metadata"><![CDATA[
    handled = false
    if (game.menucallback <> null) {
      if (HandleMenuTextResponse(command)) {
        handled = true
      }
      else {
        if (game.menuallowcancel) {
          ClearMenu
        }
        else {
          handled = true
        }
      }
    }
    if (not handled) {
      StartTurnOutputSection
      if (StartsWith (command, "*")) {
        // Modified by KV to bypass turn scripts and turn counts, and to print "Noted."
        game.suppressturnscripts = true
        msg ("")
        msg (SafeXML (command))
        msg ("Noted.")
        // Added for Quest 5.8    - KV
        FinishTurn
      }
      else {
        shownlink = false
        if (game.echocommand) {
          if (metadata <> null and game.enablehyperlinks and game.echohyperlinks) {
            foreach (key, metadata) {
              if (EndsWith(command, key)) {
                objectname = StringDictionaryItem(metadata, key)
                object = GetObject(objectname)
                if (object <> null) {
                  msg ("")
                  msg ("&gt; " + Left(command, LengthOf(command) - LengthOf(key)) + "{object:" + object.name + "}")
                  shownlink = true
                }
              }
            }
          }
          if (not shownlink) {
            msg ("")
            OutputTextRaw ("&gt; " + SafeXML(command))
          }
        }
        else {
          if (not GetBoolean(game, "notranscript") and GetBoolean(game, "savingtranscript")) {
            JS.writeToTranscript ("<span><br/>> " + SafeXML(command) + "<br/></span>")
          }
        }
        if (game.command_newline) {
          msg ("")
        }
        game.pov.commandmetadata = metadata
        if (game.multiplecommands) {
          commands = Split(command, ".")
          if (ListCount(commands) = 1) {
            game.pov.commandqueue = null
            HandleSingleCommand (Trim(command))
          }
          else {
            game.pov.commandqueue = commands
            HandleNextCommandQueueItem
          }
        }
        else {
          game.pov.commandqueue = null
          HandleSingleCommand (Trim(command))
        }
      }
    }
  ]]></function>
  <function name="HandleNextCommandQueueItem"><![CDATA[
    if (TypeOf(game.pov, "commandqueue") = "stringlist") {
      queuelength = ListCount(game.pov.commandqueue)
      if (queuelength > 0) {
        thiscommand = Trim(StringListItem(game.pov.commandqueue, 0))
        if (queuelength = 1) {
          game.pov.commandqueue = null
        }
        else {
          newqueue = NewStringList()
          for (i, 1, queuelength - 1) {
            list add (newqueue, StringListItem(game.pov.commandqueue, i))
          }
          game.pov.commandqueue = newqueue
        }
        if (LengthOf(thiscommand) > 0) {
          HandleSingleCommand (thiscommand)
        }
        else {
          HandleNextCommandQueueItem
        }
      }
    }
  ]]></function>
  <function name="HandleSingleCommandPattern" parameters="command, thiscommand, varlist">
    // current command string
    game.pov.currentcommand = command
    // current command object
    game.pov.currentcommandpattern = thiscommand
    // string dictionary of variables, e.g. object1="book"; object2="table"
    game.pov.currentcommandvarlist = varlist
    // string list of variables left to resolve
    game.pov.currentcommandvarlistqueue = NewStringList()
    foreach (key, varlist) {
      list add (game.pov.currentcommandvarlistqueue, key)
    }
    // dictionary of resolved elements, e.g. object1=book_object; object2=table_object
    game.pov.currentcommandresolvedelements = NewDictionary()
    // list of resolved elements, e.g. book_object; table_object
    game.pov.currentcommandresolvedobjects = NewObjectList()
    game.pov.currentcommandunresolvedobject = null
    game.pov.currentcommandpendingvariable = null
    ResolveNextName
  </function>
  <function name="ResolveNextName"><![CDATA[
    resolvedall = false
    queuetype = TypeOf(game.pov, "currentcommandvarlistqueue")
    if (queuetype = "stringlist") {
      queuelength = ListCount(game.pov.currentcommandvarlistqueue)
      if (queuelength > 0) {
        // Pop next variable off the queue
        var = StringListItem(game.pov.currentcommandvarlistqueue, 0)
        if (queuelength = 1) {
          game.pov.currentcommandvarlistqueue = null
        }
        else {
          newqueue = NewStringList()
          for (i, 1, queuelength - 1) {
            list add (newqueue, StringListItem(game.pov.currentcommandvarlistqueue, i))
          }
          game.pov.currentcommandvarlistqueue = newqueue
        }
        // Resolve variable
        value = StringDictionaryItem(game.pov.currentcommandvarlist, var)
        if (value <> "") {
          result = null
          resolvinglist = false
          // This is to resolve issue 626
          if (StartsWith(var, "objectexit")) {
            result = ResolveName(var, value, "exit")
          }
          if (result = null) {
            if (StartsWith(var, "object")) {
              if (GetBoolean(game.pov.currentcommandpattern, "allow_all")) {
                scope = FilterByAttribute(GetScope("object", "", "object"), "scenery", false)
                game.pov.currentcommandpendingobjectscope = ListExclude(scope, FilterByAttribute(scope, "not_all", true))
                game.pov.currentcommandpendingvariable = var
                ResolveNameList (value, "object")
                resolvinglist = true
              }
              else if (HasScript(game.pov.currentcommandpattern, "multipleobjects")) {
                game.pov.currentcommandpendingobjectlist = NewObjectList()
                game.pov.currentcommandpendingvariable = var
                do (game.pov.currentcommandpattern, "multipleobjects")
                ResolveNameList (value, "object")
                resolvinglist = true
              }
              else {
                result = ResolveName(var, value, "object")
              }
            }
            else if (StartsWith(var, "exit")) {
              result = ResolveName(var, value, "exit")
            }
            else if (StartsWith(var, "text")) {
              result = StringDictionaryItem(game.pov.currentcommandvarlist, var)
            }
            else {
              error ("Unhandled command variable '" + var + "' - command variable names must begin with 'object', 'exit' or 'text'")
            }
          }
          // at this point, ResolveName has returned - either an object name, unresolved, or pending
          if (result = null) {
            if ((not resolvinglist) and LengthOf(GetString(game.pov, "currentcommandpendingvariable")) = 0) {
              UnresolvedCommand (value, var)
            }
          }
          else {
            AddToResolvedNames (var, result)
          }
        }
        else {
          ResolveNextName
        }
      }
      else {
        resolvedall = true
      }
    }
    else if (queuetype = "null") {
      resolvedall = true
    }
    else {
      error ("Invalid queue type")
    }
    if (resolvedall) {
      // All the objects have been resolved, so now we can actually do the command
      // TO DO: game.lastobjects should be game.pov.lastobjects
      game.lastobjects = game.pov.currentcommandresolvedobjects
      if (not DictionaryContains(game.pov.currentcommandresolvedelements, "multiple")) {
        dictionary add (game.pov.currentcommandresolvedelements, "multiple", false)
      }
      if (not GetBoolean(game.pov.currentcommandpattern, "isundo")) {
        if (LengthOf(game.pov.currentcommand) > 0) {
          start transaction (game.pov.currentcommand)
        }
      }
      if (not GetBoolean(game.pov.currentcommandpattern, "isoops")) {
        // TO DO: game.unresolved* should be game.pov.unresolved*
        game.unresolvedcommand = null
        game.unresolvedcommandvarlist = null
        game.unresolvedcommandkey = null
      }
      if (DictionaryContains(game.pov.currentcommandresolvedelements, "object")) {
        game.text_processor_this = ObjectDictionaryItem(game.pov.currentcommandresolvedelements, "object")
      }
      else if (DictionaryContains(game.pov.currentcommandresolvedelements, "object1")) {
        game.text_processor_this = ObjectDictionaryItem(game.pov.currentcommandresolvedelements, "object1")
      }
      if (HasScript(game.pov.currentcommandpattern, "script")) {
        // This is the bit that actually runs the commands
        do (game.pov.currentcommandpattern, "script", game.pov.currentcommandresolvedelements)
      }
      //
      // Setting game.runturnscripts to true to run turn scripts after ShowMenu , show menu, ask, or Ask.
      // This works in conjuction with FinishTurn, which has also been modified as of Quest 5.8.
      // - KV, 2018/05/25
      game.runturnscripts = true
      FinishTurn
      HandleNextCommandQueueItem
    }
  ]]></function>
  <function name="AddToResolvedNames" parameters="var, result">
    if (TypeOf(result) = "object") {
      if (result.type = "object") {
        list add (game.pov.currentcommandresolvedobjects, result)
      }
    }
    else if (TypeOf(result) = "objectlist") {
      foreach (obj, result) {
        if (obj.type = "object") {
          list add (game.pov.currentcommandresolvedobjects, obj)
        }
      }
    }
    dictionary add (game.pov.currentcommandresolvedelements, var, result)
    ResolveNextName
  </function>
  <function name="ResolveName" parameters="variable, value, objtype" type="object"><![CDATA[
    found = false
    if (game.pov.commandmetadata <> null) {
      if (DictionaryContains(game.pov.commandmetadata, value)) {
        result = GetObject(StringDictionaryItem(game.pov.commandmetadata, value))
        if (result <> null) {
          if (ListContains(ScopeVisible(), result)) {
            found = true
            return (result)
          }
        }
      }
    }
    if (not found) {
      value = LCase(value)
      result = ResolveNameInternal(variable, value, objtype)
      if (result <> null) {
        return (result)
      }
      else {
        // TO DO: Check this behaviour. We only want to try ignoring prefixes if we have definitely got an unresolved name.
        foreach (prefix, game.parserignoreprefixes) {
          if (StartsWith(value, prefix + " ")) {
            result = ResolveNameInternal(variable, Mid(value, LengthOf(prefix) + 1), objtype)
          }
        }
        if (result = null and LengthOf(variable) = 0 and not GetBoolean(game.pov, "currentcommandmultiobjectpending")) {
          UnresolvedCommand (value, game.pov.currentcommandpendingvariable)
        }
        return (result)
      }
    }
  ]]></function>
  <function name="ResolveNameInternal" parameters="variable, value, objtype" type="object">
    game.pov.currentcommandmultiobjectpending = false
    scope = GetScope(variable, value, objtype)
    if (HasString(game.pov.currentcommandpattern, "scope")) {
      secondaryscope = ScopeVisible()
    }
    else {
      secondaryscope = null
    }
    return (ResolveNameFromList(variable, value, objtype, scope, secondaryscope))
  </function>
  <function name="ResolveNameFromList" parameters="variable, value, objtype, scope, secondaryscope" type="object"><![CDATA[
    value = Trim(LCase(value))
    fullmatches = NewObjectList()
    partialmatches = NewObjectList()
    foreach (obj, scope) {
      name = LCase(GetDisplayAlias(obj))
      CompareNames (name, value, obj, fullmatches, partialmatches)
      if (obj.alt <> null) {
        foreach (altname, obj.alt) {
          CompareNames (LCase(altname), value, obj, fullmatches, partialmatches)
        }
      }
    }
    // allow referring to objects from the previous command by gender or article
    if (objtype = "object" and game.lastobjects <> null) {
      foreach (obj, game.lastobjects) {
        CompareNames (LCase(obj.article), value, obj, fullmatches, partialmatches)
        CompareNames (LCase(obj.gender), value, obj, fullmatches, partialmatches)
      }
    }
    // Also check the secondary scope, but only if we have not found anything yet
    if (ListCount(fullmatches) = 0 and ListCount(partialmatches) = 0 and not secondaryscope = null) {
      foreach (obj, secondaryscope) {
        name = LCase(GetDisplayAlias(obj))
        CompareNames (name, value, obj, fullmatches, partialmatches)
        if (obj.alt <> null) {
          foreach (altname, obj.alt) {
            CompareNames (LCase(altname), value, obj, fullmatches, partialmatches)
          }
        }
      }
    }
    if (ListCount(fullmatches) = 1) {
      return (ListItem(fullmatches, 0))
    }
    else if (ListCount(fullmatches) = 0 and ListCount(partialmatches) = 1) {
      return (ListItem(partialmatches, 0))
    }
    else if (ListCount(fullmatches) + ListCount(partialmatches) = 0) {
      return (null)
    }
    else {
      // Added this line to resolve issue with new FinishTurn setup in 580
      game.disambiguating = true
      candidates = ListCompact(ListCombine(fullmatches, partialmatches))
      if (LengthOf(variable) > 0) {
        // single object command, so after showing the menu, add the object to game.pov.currentcommandresolvedelements
        game.pov.currentcommandpendingvariable = variable
        ShowMenu (DynamicTemplate("DisambiguateMenu", value), candidates, true) {
          varname = game.pov.currentcommandpendingvariable
          game.pov.currentcommandpendingvariable = null
          if (result <> null) {
            AddToResolvedNames (varname, GetObject(result))
          }
        }
      }
      else {
        // multi-object command, so after showing the menu, add the object to the list
        game.pov.currentcommandmultiobjectpending = true
        ShowMenu (DynamicTemplate("DisambiguateMenu", value), candidates, true) {
          if (result <> null) {
            list add (game.pov.currentcommandpendingobjectlist, GetObject(result))
            ResolveNextNameListItem
          }
        }
      }
      return (null)
    }
  ]]></function>
  <function name="ResolveNameList" parameters="value, objtype">
    game.pov.currentcommandpendingobjectlist = NewObjectList()
    game.pov.currentcommandpendingobjectlistunresolved = NewStringList()
    game.pov.currentcommandpendingobjecttype = objtype
    inputlist = Split(value, ",")
    foreach (inputbase, inputlist) {
      inputlist2 = Split(inputbase, " " + Template("And") + " ")
      foreach (input, inputlist2) {
        list add (game.pov.currentcommandpendingobjectlistunresolved, input)
      }
    }
    ResolveNextNameListItem
  </function>
  <function name="ResolveNextNameListItem"><![CDATA[
    resolvedall = false
    if (TypeOf(game.pov, "currentcommandpendingobjectlistunresolved") = "stringlist") {
      queuelength = ListCount(game.pov.currentcommandpendingobjectlistunresolved)
      if (queuelength > 0) {
        thisitem = Trim(StringListItem(game.pov.currentcommandpendingobjectlistunresolved, 0))
        if (queuelength = 1) {
          game.pov.currentcommandpendingobjectlistunresolved = null
        }
        else {
          newqueue = NewStringList()
          for (i, 1, queuelength - 1) {
            list add (newqueue, StringListItem(game.pov.currentcommandpendingobjectlistunresolved, i))
          }
          game.pov.currentcommandpendingobjectlistunresolved = newqueue
        }
        ResolveNameListItem (Trim(thisitem))
      }
      else {
        resolvedall = true
      }
    }
    else {
      resolvedall = true
    }
    if (resolvedall) {
      ResolveNameListItemFinished (game.pov.currentcommandpendingobjectlist)
    }
  ]]></function>
  <function name="ResolveNameListItem" parameters="value"><![CDATA[
    if (ListContains(game.allobjects, value)) {
      // value is "all"
      if (not DictionaryContains(game.pov.currentcommandresolvedelements, "multiple")) {
        dictionary add (game.pov.currentcommandresolvedelements, "multiple", true)
      }
      ResolveNameListItemFinished (game.pov.currentcommandpendingobjectscope)
    }
    else {
      object = ResolveName("", value, game.pov.currentcommandpendingobjecttype)
      if (object <> null) {
        if (not ListContains(game.pov.currentcommandpendingobjectlist, object)) {
          list add (game.pov.currentcommandpendingobjectlist, object)
        }
        ResolveNextNameListItem
      }
    }
  ]]></function>
  <function name="ResolveNameListItemFinished" parameters="result"><![CDATA[
    if (ListCount(result) > 1) {
      if (not DictionaryContains(game.pov.currentcommandresolvedelements, "multiple")) {
        dictionary add (game.pov.currentcommandresolvedelements, "multiple", true)
      }
    }
    AddToResolvedNames (game.pov.currentcommandpendingvariable, result)
  ]]></function>
  <function name="UnresolvedCommand" parameters="objectname, varname"><![CDATA[
    // TO DO: Update names below, we don't need these two variables
    unresolvedobject = objectname
    unresolvedkey = varname
    if (HasString(game.pov.currentcommandpattern, "unresolved")) {
      if (ListCount(game.pov.currentcommandvarlist) > 1) {
        msg (game.pov.currentcommandpattern.unresolved + " (" + unresolvedobject + ")")
      }
      else {
        msg (game.pov.currentcommandpattern.unresolved)
      }
    }
    else if (HasScript(game.pov.currentcommandpattern, "unresolved")) {
      do (game.pov.currentcommandpattern, "unresolved", QuickParams("object", unresolvedobject, "key", unresolvedkey))
    }
    else {
      if (ListCount(game.pov.currentcommandvarlist) > 1) {
        msg (Template("UnresolvedObject") + " (" + unresolvedobject + ")")
      }
      else {
        msg (Template("UnresolvedObject"))
      }
    }
    game.unresolvedcommand = game.pov.currentcommandpattern
    game.unresolvedcommandvarlist = game.pov.currentcommandvarlist
    game.unresolvedcommandkey = unresolvedkey
  ]]></function>
  <function name="HandleMultiVerb" parameters="object, property, object2, default">
    dictionary = GetAttribute(object, property)
    if (DictionaryContains(dictionary, object2.name)) {
      parameters = NewDictionary()
      dictionary add (parameters, "this", object)
      dictionary add (parameters, "object", object2)
      invoke (ScriptDictionaryItem(dictionary, object2.name), parameters)
    }
    else {
      parameters = NewDictionary()
      dictionary add (parameters, "this", object)
      dictionary add (parameters, "object", object2)
      if (DictionaryContains(dictionary, "default")) {
        invoke (ScriptDictionaryItem(dictionary, "default"), parameters)
      }
      else {
        msg (default)
      }
    }
  </function>
  <function name="GetScope" parameters="variable, value, objtype" type="objectlist"><![CDATA[
    items = NewObjectList()
    if (HasString(game.pov.currentcommandpattern, "scope")) {
      scoping = GetScoping(game.pov.currentcommandpattern.scope, variable)
      foreach (partscope, Split(scoping, ";")) {
        switch (partscope) {
          case ("inventory") {
            items = ListCombine(items, ScopeInventory())
          }
          case ("notheld", "room") {
            items = ListCombine(items, ScopeVisibleNotHeld()) - game.pov
          }
          case ("all") {
            items = ListCombine(items, ScopeVisible()) - game.pov
          }
          case ("container") {
            items = ListCombine(items, FilterByType(ScopeVisible(), "container_base"))
          }
          case ("contents") {
            foreach (cont, FilterByType(ScopeVisible(), "container_base")) {
              items = ListCombine(items, GetAllChildObjects(cont))
            }
          }
          case ("world") {
            items = ListCombine(items, AllObjects())
          }
          case ("none") {
          }
          default {
            // The command's "scope" can be the name of an object, or an attribute of the player's parent
            obj = GetObject(partscope)
            if (not obj = null) {
              items = ListCombine(items, GetAllChildObjects(obj))
            }
            if (HasObject(game.pov.parent, partscope)) {
              obj = GetAttribute(game.pov.parent, partscope)
              items = ListCombine(items, GetAllChildObjects(obj))
            }
            else if (HasAttribute(game.pov.parent, partscope)) {
              attr = GetAttribute(game.pov.parent, partscope)
              if (TypeOf(attr) = "objectlist") {
                items = ListCombine (items, attr)
              }
            }
            else if (HasAttribute(game.pov, partscope)) {
              attr = GetAttribute(game.pov, partscope)
              if (TypeOf(attr) = "objectlist") {
                items = ListCombine (items, attr)
              }
            }
          }
        }
      }
    }
    else if (objtype = "object") {
      items = ScopeVisible()
    }
    else if (objtype = "exit") {
      items = ScopeExits()
    }
    else {
      // Should never get here!
      // CHANGE: Should still never get here, but we don't return null.
      // If we get here somehow, trust user's scripts to define scope.
    }
    items = ObjectListCompact(items)
    // CHANGE: Run the script 'changecommandscope' (if it exists) for the game object, the player's room and
    // containing rooms, and the current command. This allows the user to change command scope on a per-location
    // or per-command basis
    // This script gets an "items" list parameter, like `scopebackdrop` script does; but also has parameters
    // 'command', 'variable', and 'objtype', so the user can adjust their script to give different item lists
    // for different commands, or different variables within a command.
    objectswithscripts = NewObjectList()
    if (HasScript(game.pov.currentcommandpattern, "changecommandscope")) {
      list add (objectswithscripts, game.pov.currentcommandpattern)
    }
    room = game.pov
    while (not room = null) {
      if (HasScript(room, "changecommandscope")) {
        list add (objectswithscripts, room)
      }
      room = room.parent
    }
    if (HasScript(game, "changecommandscope")) {
      list add (objectswithscripts, game)
    }
    if (ListCount(objectswithscripts) > 0) {
      params = NewDictionary()
      dictionary add (params, "items", items)
      dictionary add (params, "command", game.pov.currentcommandpattern)
      dictionary add (params, "variable", variable)
      dictionary add (params, "objtype", objtype)
      dictionary add (params, "matched", game.pov.currentcommandresolvedelements)
      foreach (o, objectswithscripts) {
        do (o, "changecommandscope", params)
      }
      items = ObjectListCompact(items)
    }
    return (items)
  ]]></function>
  <function name="GetScoping" parameters="scopestring, variable" type="string">
    lst = Split(scopestring, "|")
    if (ListCount(lst) = 1) {
      return (scopestring)
    }
    foreach (s, lst) {
      if (StartsWith(s, variable + "=")) {
        return (Mid(s, LengthOf(variable) + 2))
      }
    }
    return ("all")
  </function>
  <function name="CompareNames" parameters="name, value, obj, fullmatches, partialmatches"><![CDATA[
    if (name = value) {
      if (not ListContains(fullmatches, obj)) {
        list add (fullmatches, obj)
      }
    }
    else {
      if (StartsWith(name, value)) {
        if (not ListContains(partialmatches, obj)) {
          list add (partialmatches, obj)
        }
      }
      else {
        // check if input matches the start of any word in the name
        if (Instr(name, " " + value) > 0) {
          if (not ListContains(partialmatches, obj)) {
            list add (partialmatches, obj)
          }
        }
      }
    }
  ]]></function>
  <function name="GenerateMenuChoices" parameters="dictionary, objects">
    msg ("WARNING: GenerateMenuChoices is deprecated as ShowMenu can handle lists with objects")
    foreach (obj, objects) {
      if (not DictionaryContains(dictionary, obj.name)) {
        dictionary add (dictionary, obj.name, GetDisplayAlias(obj))
      }
    }
  </function>
  <function name="GetPlacesObjectsList" type="objectlist">
    return (ListExclude(ScopeVisibleNotHeldNotScenery(), game.pov))
  </function>
  <function name="GetExitsList" type="objectlist">
    return (RemoveLookOnlyExits(RemoveSceneryObjects(ScopeExits())))
  </function>
  <function name="ScopeInventory" type="objectlist">
    result = NewObjectList()
    foreach (obj, GetAllChildObjects(game.pov)) {
      if (ContainsVisible(game.pov, obj)) {
        list add (result, obj)
      }
    }
    return (result)
  </function>
  <function name="ScopeReachableInventory" type="objectlist">
    result = NewObjectList()
    foreach (obj, GetAllChildObjects(game.pov)) {
      if (ContainsReachable(game.pov, obj)) {
        list add (result, obj)
      }
    }
    return (result)
  </function>
  <function name="ScopeVisibleNotHeld" type="objectlist">
    return (ScopeVisibleNotHeldForRoom(game.pov.parent))
  </function>
  <function name="ScopeVisibleNotHeldForRoom" parameters="room" type="objectlist">
    if (room = game.pov.parent) {
      result = ListCombine(ScopeReachableNotHeldForRoom(room), ScopeVisibleNotReachableForRoom(room))
      list add (result, game.pov)
      return (result)
    }
    else {
      return (ListCombine(ScopeReachableNotHeldForRoom(room), ScopeVisibleNotReachableForRoom(room)))
    }
  </function>
  <function name="ScopeVisibleNotHeldNotScenery" type="objectlist">
    return (ScopeVisibleNotHeldNotSceneryForRoom(game.pov.parent))
  </function>
  <function name="ScopeVisibleNotHeldNotSceneryForRoom" parameters="room" type="objectlist">
    return (RemoveSceneryObjects(ScopeVisibleNotHeldForRoom(room)))
  </function>
  <function name="ScopeReachable" type="objectlist">
    return (ScopeReachableForRoom(game.pov.parent))
  </function>
  <function name="ScopeReachableForRoom" parameters="room" type="objectlist">
    if (room = game.pov.parent) {
      result = ListCombine(ScopeReachableNotHeldForRoom(room), ScopeReachableInventory())
      list add (result, game.pov)
    }
    else {
      result = ScopeReachableNotHeldForRoom(room)
    }
    return (result)
  </function>
  <function name="ScopeVisibleNotReachable" type="objectlist">
    return (ScopeVisibleNotReachableForRoom(game.pov.parent))
  </function>
  <function name="ScopeVisibleNotReachableForRoom" parameters="room" type="objectlist">
    result = NewObjectList()
    exclude = ScopeReachableForRoom(room)
    list add (exclude, game.pov)
    newParent = GetNonTransparentParent(room)
    foreach (obj, GetAllChildObjects(newParent)) {
      if (ContainsVisible(newParent, obj) and not ListContains(exclude, obj)) {
        list add (result, obj)
      }
    }
    return (result)
  </function>
  <function name="GetNonTransparentParent" parameters="room" type="object">
    if (GetBoolean(room, "transparent")) {
      if (room.parent = null) {
        return (room)
      }
      else {
        return (GetNonTransparentParent(room.parent))
      }
    }
    else {
      return (room)
    }
  </function>
  <function name="ScopeReachableNotHeld" type="objectlist">
    return (ScopeReachableNotHeldForRoom(game.pov.parent))
  </function>
  <function name="ScopeVisibleLightsource" parameters="lightstrength" type="objectlist">
    result = ScopeVisible()
    lightobjects = NewObjectList()
    foreach (obj, result) {
      if (GetBoolean(obj, "lightsource") and GetString(obj, "lightstrength") = lightstrength) {
        list add (lightobjects, obj)
      }
    }
    exits = ScopeExits()
    foreach (obj, exits) {
      if (GetBoolean(obj, "lightsource") and GetString(obj, "lightstrength") = lightstrength) {
        list add (lightobjects, obj)
      }
    }
    return (lightobjects)
  </function>
  <function name="ScopeReachableNotHeldForRoom" parameters="room" type="objectlist"><![CDATA[
    result = NewObjectList()
    foreach (obj, GetAllChildObjects(room)) {
      if (ContainsReachable(room, obj) and obj <> game.pov and not Contains(game.pov, obj)) {
        list add (result, obj)
      }
    }
    if (HasScript(game, "scopebackdrop")) {
      dict = NewDictionary()
      dictionary add (dict, "items", result)
      do (game, "scopebackdrop", dict)
    }
    return (result)
  ]]></function>
  <function name="ScopeVisible" type="objectlist">
    return (ScopeVisibleForRoom(game.pov.parent))
  </function>
  <function name="ScopeVisibleForRoom" parameters="room" type="objectlist">
    if (room = game.pov.parent) {
      return (ListCombine(ScopeVisibleNotHeldForRoom(room), ScopeInventory()))
    }
    else {
      return (ScopeVisibleNotHeldForRoom(room))
    }
  </function>
  <function name="ScopeExits" type="objectlist">
    return (ScopeExitsForRoom(game.pov.parent))
  </function>
  <function name="ScopeExitsForRoom" parameters="room" type="objectlist">
    result = NewObjectList()
    foreach (exit, AllExits()) {
      if (exit.parent = room) {
        if (exit.visible) {
          if (GetBoolean(room, "darklevel")) {
            if (GetBoolean(exit, "lightsource")) {
              list add (result, exit)
            }
          }
          else {
            list add (result, exit)
          }
        }
      }
    }
    return (result)
  </function>
  <function name="ScopeUnlockedExitsForRoom" parameters="room" type="objectlist">
    result = NewObjectList()
    foreach (exit, AllExits()) {
      if (exit.parent = room) {
        if (exit.visible and not exit.locked) {
          if (GetBoolean(room, "darklevel")) {
            if (GetBoolean(exit, "lightsource")) {
              list add (result, exit)
            }
          }
          else {
            list add (result, exit)
          }
        }
      }
    }
    return (result)
  </function>
  <function name="ScopeCommands" type="objectlist">
    result = NewObjectList()
    foreach (command, AllCommands()) {
      if (command.parent = null or command.parent = game.pov.parent) {
        list add (result, command)
      }
      if (not game.pov.parent.parent = null) {
        if (command.parent = game.pov.parent.parent) {
          list add (result, command)
        }
      }
    }
    return (result)
  </function>
  <function name="GetBlockingObject" parameters="obj" type="object">
    result = null
    foreach (obj, ListParents(obj)) {
      if (result = null and not CanReachThrough(obj)) {
        result = obj
      }
    }
    return (result)
  </function>
  <function name="ListParents" parameters="obj" type="objectlist"><![CDATA[
    result = NewObjectList()
    if (obj.parent <> null) {
      parent_as_list = NewObjectList()
      list add (parent_as_list, obj.parent)
      result = ListCombine(parent_as_list, ListParents(obj.parent))
    }
    return (result)
  ]]></function>
  <function name="ContainsVisible" parameters="parentObj, searchObj" type="boolean">
    return (ContainsAccessible(parentObj, searchObj, false))
  </function>
  <function name="ContainsReachable" parameters="parentObj, searchObj" type="boolean">
    return (ContainsAccessible(parentObj, searchObj, true))
  </function>
  <function name="ContainsAccessible" parameters="parentObj, searchObj, onlyReachable" type="boolean">
    if (not HasObject(searchObj, "parent")) {
      return (false)
    }
    else if (not searchObj.visible) {
      return (false)
    }
    else if (GetBoolean(parentObj, "darklevel") and not GetBoolean(searchObj, "lightsource")) {
      return (false)
    }
    else {
      if (searchObj.parent = null) {
        return (false)
      }
      else if (searchObj.parent = parentObj) {
        return (true)
      }
      else {
        if (onlyReachable) {
          canAdd = CanReachThrough(searchObj.parent)
        }
        else {
          canAdd = CanSeeThrough(searchObj.parent)
        }
        if (canAdd) {
          return (ContainsAccessible(parentObj, searchObj.parent, onlyReachable))
        }
        else {
          return (false)
        }
      }
    }
  </function>
  <function name="GetVolume" parameters="obj, allinclusive" type="int">
    result = 0
    foreach (object, GetAllChildObjects ( obj )) {
      if (HasInt(object, "volume")) {
        result = result + object.volume
      }
    }
    if (allinclusive and HasInt(obj, "volume")) {
      result = result + obj.volume
    }
    return (result)
  </function>
  <function name="CanSeeThrough" parameters="obj" type="boolean">
    return ((GetBoolean(obj, "transparent") or CanReachThrough(obj)) and not GetBoolean(obj, "hidechildren"))
  </function>
  <function name="CanReachThrough" parameters="obj" type="boolean">
    return (GetBoolean(obj, "isopen") and not GetBoolean(obj, "hidechildren"))
  </function>
  <function name="Got" parameters="obj" type="boolean">
    return (ListContains(ScopeInventory(), obj))
  </function>
  <function name="UpdateObjectLinks">
    if (game.enablehyperlinks) {
      data = NewStringDictionary()
      foreach (object, ScopeVisible()) {
        dictionary add (data, object.name, Join(GetDisplayVerbs(object), "/"))
      }
      JS.updateObjectLinks (data)
      exits = NewStringList()
      foreach (exit, ScopeExits()) {
        list add (exits, exit.name)
      }
      JS.updateExitLinks (exits)
      commands = NewStringList()
      foreach (cmd, ScopeCommands()) {
        list add (commands, cmd.name)
      }
      JS.updateCommandLinks (commands)
    }
  </function>
  <function name="SecondaryScopeReachableForRoom" parameters="room" type="objectlist">
    return (NewObjectList())
  </function>
  <function name="ShowRoomDescription"><![CDATA[
    isDark = CheckDarkness()
    if (isDark) {
      descriptionfield = "darkroomdescription"
    }
    else {
      descriptionfield = "description"
    }
    if (game.autodescription) {
      desc = ""
      for (i, 1, 4) {
        if (i = game.autodescription_youarein) {
          if (game.autodescription_youarein_useprefix) {
            youarein = game.pov.parent.descprefix
            desc = AddDescriptionLine (desc, youarein + " " + GetDisplayName(game.pov.parent) + ".")
          }
          else {
            desc = AddDescriptionLine (desc, "<b>" + CapFirst(GetDisplayName(game.pov.parent)) + "</b>")
          }
          if (game.autodescription_youarein_newline) {
            msg (desc + "<br/>")
            desc = ""
          }
        }
        if (i = game.autodescription_youcansee) {
          objects = FormatObjectList(game.pov.parent.objectslistprefix, GetNonTransparentParent(game.pov.parent), Template("And"), ".")
          desc = AddDescriptionLine(desc, objects)
          if (game.autodescription_youcansee_newline) {
            msg (desc + "<br/>")
            desc = ""
          }
        }
        if (i = game.autodescription_youcango) {
          exits = FormatExitList(game.pov.parent.exitslistprefix, GetExitsList(), Template("Or"), ".")
          desc = AddDescriptionLine(desc, exits)
          if (game.autodescription_youcango_newline) {
            msg (desc + "<br/>")
            desc = ""
          }
        }
        if (i = game.autodescription_description) {
          if (HasScript(game.pov.parent, descriptionfield)) {
            if (LengthOf(desc) > 0) {
              msg (desc)
              desc = ""
            }
            do (game.pov.parent, descriptionfield)
            if (game.autodescription_description_newline) {
              msg ("")
            }
          }
          else {
            desc = AddDescriptionLine(desc, GetRoomDescription())
            if (game.autodescription_description_newline) {
              msg (desc + "<br/>")
              desc = ""
            }
          }
        }
      }
      if (LengthOf(desc) > 0) {
        msg (desc)
      }
    }
    else {
      if (HasScript(game.pov.parent, descriptionfield)) {
        do (game.pov.parent, descriptionfield)
      }
      else {
        fulldesc = GetRoomDescription()
        if (LengthOf(fulldesc) > 0) {
          msg (fulldesc)
        }
      }
    }
  ]]></function>
  <function name="AddDescriptionLine" parameters="desc, line" type="string"><![CDATA[
    if (LengthOf(line) > 0) {
      if (LengthOf(desc) > 0) {
        msg (desc)
        desc = ""
      }
      desc = desc + line
    }
    return (desc)
  ]]></function>
  <function name="GetRoomDescription" type="string"><![CDATA[
    fulldesc = ""
    if (CheckDarkness()) {
      if (HasString(game.pov.parent, "darkroomdescription")) {
        if (LengthOf(game.pov.parent.darkroomdescription) > 0) {
          fulldesc = game.pov.parent.darkroomdescription
        }
      }
      // Added by The Pixie to correct what appears to be a bug
      if (fulldesc = "") {
        fulldesc = DynamicTemplate("LookAtDarkness", game.pov.parent)
      }
    }
    else {
      if (HasString(game.pov.parent, "description")) {
        if (LengthOf(game.pov.parent.description) > 0) {
          fulldesc = game.pov.parent.description
        }
      }
    }
    if (game.appendobjectdescription) {
      foreach (val, ScopeVisibleNotHeld()) {
        if (HasString(val, "inroomdescription")) {
          if (LengthOf(val.inroomdescription) > 0 and val <> game.pov) {
            fulldesc = fulldesc + " " + val.inroomdescription
          }
        }
      }
    }
    return (Trim(fulldesc))
  ]]></function>
  <function name="OnEnterRoom" parameters="oldRoom"><![CDATA[
    game.displayroomdescriptiononstart = false
    if (IsDefined("oldRoom")) {
      if (oldRoom <> null) {
        if (game.clearscreenonroomenter) {
          ClearScreen
          if (not game.currentexitmessage = null) {
            msg (game.currentexitmessage)
            game.currentexitmessage = null
          }
        }
        if (HasScript(oldRoom, "onexit")) {
          do (oldRoom, "onexit")
        }
      }
    }
    on ready {
      if ((not GetBoolean(game.pov.parent, "visited")) and HasScript(game.pov.parent, "beforefirstenter")) {
        do (game.pov.parent, "beforefirstenter")
      }
      on ready {
        if (HasScript(game.pov.parent, "beforeenter")) {
          do (game.pov.parent, "beforeenter")
        }
        on ready {
          if (game.gridmap) {
            Grid_CalculateMapCoordinates (game.pov.parent, game.pov)
            Grid_DrawPlayerInRoom (game.pov.parent)
          }
          if (IsDefined("oldRoom")) {
            if (oldRoom <> null and game.changeroom_newline and not game.command_newline) {
              msg ("")
            }
          }
          JS.updateLocation (CapFirst(GetDisplayName(game.pov.parent)))
          roomFrameExists = false
          if (HasString(game.pov.parent, "picture")) {
            if (LengthOf(game.pov.parent.picture) > 0) {
              roomFrameExists = true
              SetFramePicture (game.pov.parent.picture)
            }
          }
          if (game.clearframe and not roomFrameExists) {
            ClearFramePicture
          }
          if (game.showdescriptiononenter) {
            ShowRoomDescription
          }
          if (HasScript( game, "roomenter")) {
            do (game, "roomenter")
          }
          on ready {
            if ((not GetBoolean(game.pov.parent, "visited")) and HasScript(game.pov.parent, "firstenter")) {
              do (game.pov.parent, "firstenter")
            }
            on ready {
              if (HasScript(game.pov.parent, "enter")) {
                do (game.pov.parent, "enter")
              }
            }
            set (game.pov.parent, "visited", true)
          }
        }
      }
    }
  ]]></function>
  <function name="FormatObjectList" parameters="preList, parent, preFinal, postList" type="string"><![CDATA[
    result = ""
    count = 0
    list = RemoveSceneryObjects(GetDirectChildren(parent))
    if (CheckDarkness()) {
      list = RemoveDarkObjects(list)
    }
    listLength = ListCount(list)
    foreach (item, list) {
      if (LengthOf(result) = 0) {
        result = preList + " "
      }
      result = result + GetDisplayNameLink(item, "object")
      if (CanSeeThrough(item)) {
        result = result + FormatObjectList(" (" + item.contentsprefix, item, preFinal, ")")
      }
      count = count + 1
      if (count = listLength - 1) {
        result = result + " " + preFinal + " "
      }
      else if (count < listLength) {
        result = result + ", "
      }
      else {
        result = result + postList
      }
    }
    return (result)
  ]]></function>
  <function name="RemoveSceneryObjects" parameters="list" type="objectlist"><![CDATA[
    result = NewObjectList()
    foreach (obj, list) {
      if (not obj.scenery and obj <> game.pov and obj.visible) {
        list add (result, obj)
      }
    }
    return (result)
  ]]></function>
  <function name="RemoveLookOnlyExits" parameters="list" type="objectlist">
    result = NewObjectList()
    foreach (obj, list) {
      if (not obj.lookonly) {
        list add (result, obj)
      }
    }
    return (result)
  </function>
  <function name="RemoveDarkObjects" parameters="list" type="objectlist">
    result = NewObjectList()
    foreach (obj, list) {
      if (GetBoolean(obj, "lightsource") or obj.parent = game.pov) {
        list add (result, obj)
      }
    }
    return (result)
  </function>
  <function name="FormatExitList" parameters="preList, list, preFinal, postList" type="string"><![CDATA[
    result = ""
    listLength = ListCount(list)
    if (listLength > 0) {
      count = 0
      result = preList + " "
      foreach (item, list) {
        result = result + GetDisplayNameLink(item, "exit")
        count = count + 1
        if (count = listLength - 1) {
          result = result + " " + preFinal + " "
        }
        else if (count < listLength) {
          result = result + ", "
        }
      }
      result = result + postList
    }
    return (result)
  ]]></function>
  <function name="GetDisplayAlias" parameters="obj" type="string">
    if (HasString(obj, "alias")) {
      result = obj.alias
    }
    else {
      result = obj.name
    }
    return (result)
  </function>
  <function name="GetDisplayName" parameters="obj" type="string">
    return (GetDisplayNameLink(obj, ""))
  </function>
  <function name="GetDisplayNameLink" parameters="obj, type" type="string"><![CDATA[
    verbs = GetDisplayVerbs(obj)
    if (verbs <> null) {
      verbCount = ListCount(verbs)
    }
    else {
      verbCount = 0
    }
    if (type = "exit" and verbCount = 1) {
      if (not game.enablehyperlinks) {
        result = GetDisplayAlias(obj)
      }
      else {
        result = "{exit:" + obj.name + "}"
      }
    }
    else if (type = "") {
      result = GetDisplayAlias(obj)
    }
    else {
      result = "{object:" + obj.name + "}"
    }
    if (not GetBoolean(obj, "usedefaultprefix")) {
      if (obj.prefix = null) {
        prefix = ""
      }
      else {
        prefix = obj.prefix
      }
    }
    else if (type = "exit") {
      prefix = ""
    }
    else {
      prefix = GetDefaultPrefix(obj)
    }
    if (LengthOf(prefix) > 0) {
      prefix = prefix + " "
    }
    result = prefix + result
    if (not GetBoolean(obj, "usedefaultprefix") and HasString(obj, "suffix")) {
      if (LengthOf(obj.suffix) > 0) {
        result = result + " " + obj.suffix
      }
    }
    return (result)
  ]]></function>
  <function name="ObjectLink" parameters="obj" type="string">
    return ("{object:" + obj.name + "}")
  </function>
  <function name="GetListDisplayAlias" parameters="obj" type="string">
    if (HasString(obj, "listalias")) {
      result = obj.listalias
    }
    else {
      result = GetDisplayAlias(obj)
    }
    return (result)
  </function>
  <function name="CheckDarkness" type="boolean"><![CDATA[
    roomCheckDarkness = true
    if (GetBoolean(game.pov.parent, "dark")) {
      if (ListCount(ScopeVisibleLightsource("strong")) > 0) {
        roomCheckDarkness = false
      }
    }
    else {
      roomCheckDarkness = false
    }
    game.pov.parent.darklevel = roomCheckDarkness
    return (roomCheckDarkness)
  ]]></function>
  <function name="EnableTimer" parameters="timer">
    timer.enabled = true
    timer.trigger = game.timeelapsed + timer.interval
  </function>
  <function name="DisableTimer" parameters="timer">
    timer.enabled = false
  </function>
  <function name="SetTimerInterval" parameters="timer, interval">
    timer.interval = interval
  </function>
  <function name="SetTimerScript" parameters="timer, script">
    timer.script = script
  </function>
  <function name="SetTimeout" parameters="interval, script">
    SetTimeoutID (interval, "", script)
  </function>
  <function name="SetTimeoutID" parameters="interval, name, script">
    timername = ""
    if (name = "") {
      timername = GetUniqueElementName("timeout")
    }
    else {
      if (GetTimer(name) = null and GetObject(name) = null) {
        timername = name
      }
      else {
        error ("Error creating timer: There is already an existing object named " + name)
      }
    }
    if (not timername = "") {
      create timer (timername)
      timer = GetTimer(timername)
      SetTimerInterval (timer, interval)
      timer.timeoutscript = script
      SetTimerScript (timer) {
        this.enabled = false
        invoke (this.timeoutscript)
        JS.scrollToEnd ()
        destroy (this.name)
      }
      EnableTimer (timer)
    }
  </function>
  <function name="Pause" parameters="interval">
    error ("The Pause function is obsolete as of Quest 5.5")
  </function>
  <function name="RunTurnScripts">
    if (IsGameRunning()) {
      if (game.menucallback = null) {
        foreach (turnscript, ObjectListSort(AllTurnScripts(), "name")) {
          if (GetBoolean(turnscript, "enabled")) {
            inscope = false
            if (turnscript.parent = game or turnscript.parent = null) {
              inscope = true
            }
            else {
              if (Contains(turnscript.parent, game.pov)) {
                inscope = true
              }
            }
            if (inscope) {
              do (turnscript, "script")
            }
          }
        }
      }
    }
  </function>
  <function name="EnableTurnScript" parameters="turnscript">
    turnscript.enabled = true
  </function>
  <function name="DisableTurnScript" parameters="turnscript">
    turnscript.enabled = false
  </function>
  <function name="SetTurnScript" parameters="turnscript, script">
    turnscript.script = script
  </function>
  <function name="SetTurnTimeout" parameters="turncount, script">
    SetTurnTimeoutID (turncount, "", script)
  </function>
  <function name="SetTurnTimeoutID" parameters="turncount, name, script"><![CDATA[
    turnscriptname = ""
    if (name = "") {
      turnscriptname = GetUniqueElementName("turnscript")
    }
    else {
      if (GetObject(name) = null and GetTimer(name) = null) {
        turnscriptname = name
      }
      else {
        error ("Error creating turnscript: There is already an existing object named " + name)
      }
    }
    if (not turnscriptname="") {
      create turnscript (turnscriptname)
      turnscript = GetObject(turnscriptname)
      turnscript.turncount = 0
      turnscript.triggerturncount = turncount
      turnscript.timeoutscript = script
      SetTurnScript (turnscript) {
        this.turncount = this.turncount + 1
        if (this.turncount >= this.triggerturncount) {
          this.enabled = false
          invoke (this.timeoutscript)
          destroy (this.name)
        }
      }
      EnableTurnScript (turnscript)
    }
  ]]></function>
  <function name="SuppressTurnscripts">
    game.suppressturnscripts = true
  </function>
  <function name="UpdateStatusAttributes"><![CDATA[
    status = NewStringList()
    AddStatusAttributesForElement (status, game, game.statusattributes)
    AddStatusAttributesForElement (status, game.pov, game.povstatusattributes)
    AddStatusAttributesForElement (status, game.pov, game.pov.statusattributes)
    JS.updateStatus (Join(status, "<br/>"))
  ]]></function>
  <function name="AddStatusAttributesForElement" parameters="status, element, statusAttributes" type="string">
    if (not statusAttributes = null) {
      foreach (attr, statusAttributes) {
        list add (status, FormatStatusAttribute(attr, GetAttribute(element, attr), StringDictionaryItem(statusAttributes, attr)))
      }
    }
  </function>
  <function name="FormatStatusAttribute" parameters="attr, value, format" type="string">
    if (LengthOf(format) = 0) {
      return (CapFirst(attr) + ": " + value)
    }
    else {
      if (TypeOf(value) = "int" and attr = "money" and HasString(game, "moneyformat")) {
        value = DisplayMoney(value)
      }
      else if (TypeOf(value) = "int" or TypeOf(value) = "double") {
        value = ToString(value)
      }
      else if (TypeOf(value) = "null") {
        value = ""
      }
      return (Replace(format, "!", "" + value))
    }
  </function>
  <function name="InitStatusAttributes">
    if (game.showscore) {
      game.score = 0
      if (game.statusattributes = null) {
        game.statusattributes = NewStringDictionary()
      }
      dictionary add (game.statusattributes, "score", "Score: !")
    }
    if (game.showhealth) {
      if (game.povstatusattributes = null) {
        game.povstatusattributes = NewStringDictionary()
      }
      dictionary add (game.povstatusattributes, "health", "Health: !%")
    }
    if (game.showmoney) {
      if (game.povstatusattributes = null) {
        game.povstatusattributes = NewStringDictionary()
      }
      dictionary add (game.povstatusattributes, "money", "Money: !")
    }
  </function>
  <function name="IncreaseScore" parameters="amount">
    if (not HasInt(game, "score")) {
      error ("Score is not configured. To enable score, go to 'game' and tick 'Show score' on the Player tab.")
    }
    game.score = game.score + amount
  </function>
  <function name="DecreaseScore" parameters="amount">
    if (not HasInt(game, "score")) {
      error ("Score is not configured. To enable score, go to 'game' and tick 'Show score' on the Player tab.")
    }
    game.score = game.score - amount
  </function>
  <function name="IncreaseHealth" parameters="amount">
    if (not HasInt(game.pov, "health")) {
      error ("Health is not configured. To enable health, go to 'game' and tick 'Show health' on the Player tab.")
    }
    game.pov.health = game.pov.health + amount
  </function>
  <function name="DecreaseHealth" parameters="amount">
    if (not HasInt(game.pov, "health")) {
      error ("Health is not configured. To enable health, go to 'game' and tick 'Show health' on the Player tab.")
    }
    game.pov.health = game.pov.health - amount
  </function>
  <function name="IncreaseMoney" parameters="amount">
    if (not HasInt(game.pov, "money")) {
      error ("Money is not configured. To enable money, go to 'game' and tick 'Show money' on the Player tab.")
    }
    game.pov.money = game.pov.money + amount
  </function>
  <function name="DecreaseMoney" parameters="amount">
    if (not HasInt(game.pov, "money")) {
      error ("Money is not configured. To enable money, go to 'game' and tick 'Show money' on the Player tab.")
    }
    game.pov.money = game.pov.money - amount
  </function>
  <function name="OutputText" parameters="text">
    OutputTextRaw (ProcessText(text))
  </function>
  <function name="OutputTextRaw" parameters="text"><![CDATA[
    format = GetCurrentTextFormat("")
    JS.addText ("<span style=\"" + format + "\">" + text + "</span><br/>")
    if (GetString(game, "commandbarformat") <> format) {
      ResetCommandBarFormat
    }
    RequestSpeak (text)
  ]]></function>
  <function name="ResetCommandBarFormat">
    format = GetCurrentTextFormat("") + ";background:" + game.defaultbackground
    game.commandbarformat = format
    JS.setCommandBarStyle (format)
  </function>
  <function name="OutputTextNoBr" parameters="text">
    OutputTextRawNoBr (ProcessText(text))
  </function>
  <function name="OutputTextRawNoBr" parameters="text"><![CDATA[
    JS.addText ("<span style=\"" + GetCurrentTextFormat("") + "\">" + text + "</span>")
    RequestSpeak (text)
  ]]></function>
  <function name="GetCurrentTextFormat" parameters="colour" type="string"><![CDATA[
    style = ""
    if (UIOptionUseGameFont()) {
      font = GetCurrentFontFamily()
    }
    else {
      font = GetUIOption("OverrideFontName")
    }
    if (LengthOf(font) > 0) {
      style = style + "font-family:" + font + ";"
    }
    if (LengthOf(colour) = 0) {
      if (UIOptionUseGameColours()) {
        colour = game.defaultforeground
      }
      else {
        colour = GetUIOption("OverrideForeground")
      }
    }
    if (LengthOf(colour) > 0) {
      style = style + "color:" + colour + ";"
    }
    if (UIOptionUseGameFont()) {
      size = game.defaultfontsize
    }
    else {
      size = ToDouble(GetUIOption("OverrideFontSize"))
    }
    if (size > 0) {
      style = style + "font-size:" + ToString(size) + "pt;"
    }
    return (style)
  ]]></function>
  <function name="GetCurrentLinkTextFormat" type="string">
    return (GetCurrentTextFormat(GetLinkTextColour()))
  </function>
  <function name="UIOptionUseGameFont" type="boolean">
    value = GetUIOption("UseGameFont")
    if (value = null or value = "true") {
      return (true)
    }
    else {
      return (false)
    }
  </function>
  <function name="UIOptionUseGameColours" type="boolean">
    value = GetUIOption("UseGameColours")
    if (value = null or value = "true") {
      return (true)
    }
    else {
      return (false)
    }
  </function>
  <function name="ParamsForTextProcessor" type="dictionary">
    params = NewDictionary()
    if (not game.text_processor_this = null) {
      dictionary add (params, "this", game.text_processor_this)
    }
    if (HasAttribute(game, "text_processor_variables")) {
      foreach (key, game.text_processor_variables) {
        if (not key = "this" or game.text_processor_this = null) {
          dictionary add (params, key, DictionaryItem(game.text_processor_variables, key))
        }
      }
    }
    return (params)
  </function>
  <function name="ObjectForTextProcessor" parameters="objectname" type="object">
    if (not game.text_processor_this = null and objectname = "this") {
      object = game.text_processor_this
      if (TypeOf(object) = "object") {
        return (object)
      }
    }
    if (not game.text_processor_variables = null and DictionaryContains (game.text_processor_variables, objectname)) {
      object = DictionaryItem(game.text_processor_variables, objectname)
      if (TypeOf(object) = "object") {
        return (object)
      }
    }
    return (GetObject(objectname))
  </function>
  <function name="GetLinkTextColour" type="string">
    if (UIOptionUseGameColours()) {
      return (game.defaultlinkforeground)
    }
    else {
      return (GetUIOption("OverrideLinkForeground"))
    }
  </function>
  <function name="ProcessText" parameters="text" type="string">
    data = NewDictionary()
    dictionary add (data, "fulltext", text)
    text = ProcessTextSection(text, data)
    return (Replace(Replace(text, "@@@open@@@", "{"), "@@@close@@@", "}"))
  </function>
  <function name="ProcessTextSection" parameters="text, data" type="string"><![CDATA[
    containsUnprocessedSection = false
    open = Instr(text, "{")
      if (open > 0) {
        nestCount = 1
        searchStart = open + 1
        finished = false
        while (not finished) {
          nextOpen = Instr(searchStart, text, "{")
            nextClose = Instr(searchStart, text, "}")
          if (nextClose > 0) {
            if (nextOpen > 0 and nextOpen < nextClose) {
              nestCount = nestCount + 1
              searchStart = nextOpen + 1
            }
            else {
              nestCount = nestCount - 1
              searchStart = nextClose + 1
              if (nestCount = 0) {
                close = nextClose
                containsUnprocessedSection = true
                finished = true
              }
            }
          }
          else {
            finished = true
          }
        }
      }
      if (containsUnprocessedSection) {
        section = Mid(text, open + 1, close - open - 1)
        value = ProcessTextCommand(section, data)
        value = ProcessTextSection(value, data)
        text = Left(text, open - 1) + value + ProcessTextSection(Mid(text, close + 1), data)
      }
      return (text)
  ]]></function>
  <function name="ProcessTextCommand" parameters="section, data" type="string">
    params = NewDictionary()
    dictionary add (params, "section", section)
    dictionary add (params, "data", data)
    foreach (command, game.textprocessorcommands) {
      if (StartsWith(section, command)) {
        invoke (ScriptDictionaryItem(game.textprocessorcommands, command), params)
        if (HasString(game, "textprocessorcommandresult")) {
          result = game.textprocessorcommandresult
          game.textprocessorcommandresult = null
          return (result)
        }
      }
    }
    dot = Instr(section, ".")
    if (dot = 0) {
      return ("@@@open@@@" + ProcessTextSection(section, data) + "@@@close@@@")
    }
    else {
      objectname = Left(section, dot - 1)
      attributename = Mid(section, dot + 1)
      object = ObjectForTextProcessor(objectname)
      if (object = null) {
        return ("@@@open@@@" + ProcessTextSection(section, data) + "@@@close@@@")
      }
      else {
        if (HasAttribute(object, attributename)) {
          type = TypeOf(object, attributename)
          switch (type) {
            case ("string", "int", "double") {
              return (ToString(GetAttribute(object, attributename)))
            }
            case ("boolean") {
              result = GetAttribute(object, attributename)
              if (result) {
                return ("true")
              }
              else {
                return ("false")
              }
            }
            default {
              return ("(" + type + ")")
            }
          }
        }
        else {
          return ("")
        }
      }
    }
  </function>
  <function name="ProcessTextCommand_Eval" parameters="section, data" type="string">
    if (StartsWith(section, "=")) {
      section = Mid(section, 2)
    }
    else {
      section = Mid(section, 6)
    }
    if (not IsRegexMatch("[^\\w\\s]", section, "tp_punctuation_check")) {
      section = section + "()"
    }
    return (ToString(eval(section, ParamsForTextProcessor())))
  </function>
  <function name="ProcessTextCommand_Either" parameters="section, data" type="string">
    command = Mid(section, 8)
    l = Tsplit(command)
    if (ListCount(l) = 1) {
      return ("@@@open@@@either " + command + "@@@close@@@")
    }
    condition = StringListItem(l, 0)
    text = StringListItem(l, 1)
    if (ListCount(l) = 2) {
      sep = Instr(text, "|")
      if (sep = 0) {
        text2 = ""
      }
      else {
        text2 = Mid(text, sep + 1)
        text = Replace(text, "|" + text2, "")
      }
    }
    else {
      text2 = StringListItem(l, 2)
    }
    result = eval(condition, ParamsForTextProcessor())
    if (result) {
      return (ProcessTextSection(text, data))
    }
    else {
      if (text2 = "") {
        return ("")
      }
      else {
        return (ProcessTextSection(text2, data))
      }
    }
  </function>
  <function name="ProcessTextCommand_Here" parameters="section, data" type="string">
    if (StartsWith(section, "here")) {
      flag = true
      command = Mid(section, 6)
    }
    else {
      flag = false
      command = Mid(section, 9)
    }
    colon = Instr(command, ":")
    if (colon = 0) {
      return ("@@@open@@@" + section + "@@@close@@@")
    }
    else {
      text = Mid(command, colon + 1)
      condition = Left(command, colon - 1)
      object = Eval(condition, ParamsForTextProcessor())
      if (object = null) {
        return ("@@@open@@@" + section + "@@@close@@@")
      }
      if (object.parent = game.pov.parent and flag) {
        return (ProcessTextSection(text, data))
      }
      else if (not object.parent = game.pov.parent and not flag) {
        return (ProcessTextSection(text, data))
      }
      else {
        return ("")
      }
    }
  </function>
  <function name="ProcessTextCommand_If" parameters="section, data" type="string"><![CDATA[
    command = Mid(section, 4)
    colon = Instr(command, ":")
    if (colon = 0) {
      return ("@@@open@@@if " + command + "@@@close@@@")
    }
    else {
      text = Mid(command, colon + 1)
      condition = Left(command, colon - 1)
      if (not game.text_processor_this = null) {
        condition = Replace(condition, "this", game.text_processor_this.name)
      }
      operator = Instr(condition, "<=")
      if (operator <> 0) {
        operatorlength = 2
      }
      if (operator = 0) {
        operator = Instr(condition, ">=")
        if (operator <> 0) {
          operatorlength = 2
        }
      }
      if (operator = 0) {
        operator = Instr(condition, "<>")
        if (operator <> 0) {
          operatorlength = 2
        }
      }
      if (operator = 0) {
        operator = Instr(condition, "<")
        if (operator <> 0) {
          operatorlength = 1
        }
      }
      if (operator = 0) {
        operator = Instr(condition, ">")
        if (operator <> 0) {
          operatorlength = 1
        }
      }
      if (operator = 0) {
        operator = Instr(condition, "=")
        if (operator <> 0) {
          operatorlength = 1
        }
      }
      if (operator = 0) {
        checkfor = true
        if (StartsWith(condition, "not ")) {
          checkfor = false
          condition = Mid(condition, 5)
        }
        dot = Instr(condition, ".")
        if (dot = 0) {
          result = GetBoolean(game, condition)
        }
        else {
          objectname = Left(condition, dot - 1)
          attributename = Mid(condition, dot + 1)
          object = ObjectForTextProcessor(objectname)
          if (object = null) {
            result = false
          }
          else {
            result = GetBoolean(object, attributename)
          }
        }
        if (result = checkfor) {
          return (ProcessTextSection(text, data))
        }
        else {
          return ("")
        }
      }
      else {
        lhs = Left(condition, operator - 1)
        rhs = Mid(condition, operator + operatorlength)
        op = Mid(condition, operator, operatorlength)
        dot = Instr(lhs, ".")
        if (dot = 0) {
          objectname = ""
          attributename = ""
          if (HasInt(game, lhs)) {
            objectname = "game"
            attributename = lhs
          }
          else {
            return ("@@@open@@@if " + command + "@@@close@@@")
          }
        }
        else {
          objectname = Left(lhs, dot - 1)
          attributename = Mid(lhs, dot + 1)
        }
        object = ObjectForTextProcessor(objectname)
        if (object = null) {
          return ("@@@open@@@if " + command + "@@@close@@@")
        }
        else if (not HasAttribute(object, attributename)) {
          return ("@@@open@@@if " + command + "@@@close@@@")
        }
        else {
          value = GetAttribute(object, attributename)
          if (TypeOf(value) = "object") {
            value = value.name
          }
          if (op = "=") {
            if (ToString(value) = rhs) {
              return (ProcessTextSection(text, data))
            }
            else {
              return ("")
            }
          }
          else if (op = "<>") {
            if (not ToString(value) = rhs) {
              return (ProcessTextSection(text, data))
            }
            else {
              return ("")
            }
          }
          else if (op = ">") {
            if (ToDouble(ToString(value)) > ToDouble(rhs)) {
              return (ProcessTextSection(text, data))
            }
            else {
              return ("")
            }
          }
          else if (op = "<") {
            if (ToDouble(ToString(value)) < ToDouble(rhs)) {
              return (ProcessTextSection(text, data))
            }
            else {
              return ("")
            }
          }
          else if (op = ">=") {
            if (ToDouble(ToString(value)) >= ToDouble(rhs)) {
              return (ProcessTextSection(text, data))
            }
            else {
              return ("")
            }
          }
          else if (op = "<=") {
            if (ToDouble(ToString(value)) <= ToDouble(rhs)) {
              return (ProcessTextSection(text, data))
            }
            else {
              return ("")
            }
          }
        }
      }
    }
  ]]></function>
  <function name="ProcessTextCommand_Format" parameters="section, data" type="string"><![CDATA[
    html = Mid(section, 1, 1)
    section = Mid(section, 3)
    return (ProcessTextSection("<" + html + ">" + section + "</" + html + ">", data))
  ]]></function>
  <function name="ProcessTextCommand_Colour" parameters="section, data" type="string"><![CDATA[
    ary = Split(section, ":")
    com = StringListItem(ary, 0)
    c = StringListItem(ary, 1)
    list remove (ary, com)
    list remove (ary, c)
    s = Join (ary, ":")
    if (com = "back") {
      return (ProcessTextSection("<span style=\"background-color:" + c + ";\">" + s + "</span>", data))
    }
    else {
      return (ProcessTextSection("<span style=\"color:" + c + ";\">" + s + "</span>", data))
    }
  ]]></function>
  <function name="ProcessTextCommand_Popup" parameters="section, data" type="string"><![CDATA[
    section = Mid(section, 7)
    ary = Split(section, ":")
    s1 = StringListItem(ary, 0)
    list remove (ary, s1)
    s2 = Join (ary, ":")
    id = JSSafe(s1) + GetRandomInt(0, 999999999)
    link = game.defaultlinkforeground
    if (HasString(game, "altlinkforeground")) {
      link = game.altlinkforeground
    }
    s = "<span  style=\"cursor:pointer;color:" + link + ";\" onclick=\"$('#" + id + "').css('display', 'block');\">" + s1 + "</span><div id=\"" + id + "\" class=\"w3-theme-border\" style=\"position:fixed;z-index:9999;display:none;cursor:pointer;left:50px;top:40%;width:40%;background-color:" + game.defaultbackground + ";border:2px solid " + game.defaultforeground + ";color:" + link + ";border-radius:5px;padding:5px;\" onclick=\"$('#" + id + "').css('display', 'none');\"><p>"
    s = s + s2 + "</p></div>"
    return (ProcessTextSection(s, data))
  ]]></function>
  <function name="ProcessTextCommand_Object" parameters="section, data" type="string"><![CDATA[
    objectname = Mid(section, 8)
    text = ""
    colon = Instr(objectname, ":")
    if (colon > 0) {
      text = Mid(objectname, colon + 1)
      objectname = Left(objectname, colon - 1)
    }
    object = ObjectForTextProcessor(objectname)
    if (object = null) {
      return ("@@@open@@@" + ProcessTextSection(section, data) + "@@@close@@@")
    }
    else {
      if (LengthOf(text) = 0) {
        text = SafeXML(GetDisplayAlias(object))
      }
      if (game.enablehyperlinks) {
        linkid = ProcessTextCommand_GetNextLinkId()
        colour = ""
        if (HasString(object, "linkcolour") and GetUIOption("UseGameColours") = "true") {
          colour = object.linkcolour
        }
        else {
          colour = GetLinkTextColour()
        }
        style = GetCurrentTextFormat(colour)
        return ("<a id=\"" + linkid + "\" style=\"" + style + "\" class=\"cmdlink elementmenu\" data-elementid=\"" + object.name + "\">" + text + "</a>")
      }
      else {
        return (text)
      }
    }
  ]]></function>
  <function name="ProcessTextCommand_GetNextLinkId" type="string">
    if (not HasInt(game, "lastlinkid")) {
      game.lastlinkid = 0
    }
    game.lastlinkid = game.lastlinkid + 1
    return ("verblink" + game.lastlinkid)
  </function>
  <function name="ProcessTextCommand_Command" parameters="section, data" type="string"><![CDATA[
    colon = Instr(section, ":")
    command = Mid(section, colon + 1)
    text = command
    colon = Instr(command, ":")
    if (colon > 0) {
      text = Mid(command, colon + 1)
      command = Left(command, colon - 1)
    }
    style = GetCurrentLinkTextFormat()
    candidates = NewObjectList()
    foreach (cmd, ScopeCommands()) {
      if (IsRegexMatch(cmd.pattern, command, cmd.name)) {
        list add (candidates, cmd)
      }
    }
    elementid = ""
    if (ListCount(candidates) = 1) {
      cmd = ObjectListItem(candidates, 0)
      elementid = cmd.name
    }
    linkid = ProcessTextCommand_GetNextLinkId()
    dataattrs = ""
    if (game.deactivatecommandlinks) {
      dataattrs = dataattrs + "data-deactivateonclick=\"true\" "
    }
    dataattrs = dataattrs + "data-command=\"" + command + "\""
    return ("<a id=\"" + linkid + "\" style=\"" + style + "\" class=\"cmdlink commandlink\" data-elementid=\"" + elementid + "\" " + dataattrs + ">" + ProcessTextSection(text, data) + "</a>")
  ]]></function>
  <function name="ProcessTextCommand_Exit" parameters="section, data" type="string"><![CDATA[
    exitname = Mid(section, 6)
    exit = GetObject(exitname)
    if (exit = null) {
      return ("@@@open@@@" + ProcessTextSection(section, data) + "@@@close@@@")
    }
    else {
      verbs = GetDisplayVerbs(exit)
      alias = GetDisplayAlias(exit)
      command = LCase(StringListItem(verbs, 0)) + " " + alias
      style = GetCurrentLinkTextFormat()
      return ("<a style=\"" + style + "\" class=\"cmdlink exitlink\" data-elementid=\"" + exit.name + "\" data-command=\"" + command + "\">" + alias + "</a>")
    }
  ]]></function>
  <function name="ProcessTextCommand_Once" parameters="section, data" type="string">
    if (not HasAttribute(game, "textprocessor_seen")) {
      game.textprocessor_seen = NewDictionary()
    }
    fulltext = StringDictionaryItem(data, "fulltext")
    if (not DictionaryContains(game.textprocessor_seen, fulltext)) {
      onceSectionsInThisText = NewList()
      dictionary add (game.textprocessor_seen, fulltext, onceSectionsInThisText)
    }
    else {
      onceSectionsInThisText = DictionaryItem(game.textprocessor_seen, fulltext)
    }
    if (not ListContains(onceSectionsInThisText, section)) {
      list add (onceSectionsInThisText, section)
      return (ProcessTextSection(Mid(section, 6), data))
    }
    else {
      return ("")
    }
  </function>
  <function name="ProcessTextCommand_NotFirst" parameters="section, data" type="string">
    if (not HasAttribute(game, "textprocessor_seen")) {
      game.textprocessor_seen = NewDictionary()
    }
    fulltext = StringDictionaryItem(data, "fulltext")
    if (not DictionaryContains(game.textprocessor_seen, fulltext)) {
      onceSectionsInThisText = NewList()
      dictionary add (game.textprocessor_seen, fulltext, onceSectionsInThisText)
    }
    else {
      onceSectionsInThisText = DictionaryItem(game.textprocessor_seen, fulltext)
    }
    if (not ListContains(onceSectionsInThisText, section)) {
      list add (onceSectionsInThisText, section)
      return ("")
    }
    else {
      return (ProcessTextSection(Mid(section, 10), data))
    }
  </function>
  <function name="ProcessTextCommand_Random" parameters="section, data" type="string">
    elements = Mid(section, 8)
    elementslist = Tsplit(elements)
    index = GetRandomInt(0, ListCount(elementslist) - 1)
    return (ProcessTextSection(ListItem(elementslist, index), data))
  </function>
  <function name="Tsplit" parameters="splittext" type="stringlist"><![CDATA[
    itemlist = NewStringList()
    sections = 0
    startpos = 1
    for (i, 1, LengthOf(splittext)) {
      if (Mid(splittext, i, 1) = "{") {
          sections = sections + 1
        }
        if (Mid(splittext, i, 1) = "}") {
        sections = sections - 1
      }
      if (Mid(splittext, i, 1) = ":" and 0 >= sections) {
        item = Mid(splittext, startpos, i - startpos)
        list add (itemlist, item)
        startpos = i + 1
      }
    }
    item = Mid(splittext, startpos)
    list add (itemlist, item)
    return (itemlist)
  ]]></function>
  <function name="ProcessTextCommand_RandomAlias" parameters="section, data" type="string"><![CDATA[
    objectname = Mid(section, 8)
    object = ObjectForTextProcessor(objectname)
    if (object = null) {
      return ("@@@open@@@" + ProcessTextSection(section, data) + "@@@close@@@")
    }
    else {
      count = ListCount(object.alt)
      if (count > 0) {
        return (ListItem(object.alt, GetRandomInt(0, count - 1)))
      }
      else {
        return ("")
      }
    }
  ]]></function>
  <function name="ProcessTextCommand_Img" parameters="section, data" type="string"><![CDATA[
    filename = Mid(section, 5)
    return ("<img src=\"" + GetFileURL(filename) + "\" />")
  ]]></function>
  <function name="ProcessTextCommand_Counter" parameters="section, data" type="string">
    section = Mid(section, 9)
    if (HasAttribute(game, section)) {
      return (ToString(GetAttribute(game, section)))
    }
    else {
      return ("0")
    }
  </function>
  <function name="ProcessTextCommand_Select" parameters="section, data" type="string"><![CDATA[
    elements = Mid(section, 8)
    elementslist = Tsplit(elements)
    objectandatt = StringListItem (elementslist, 0)
    list remove (elementslist, objectandatt)
    objectandattlist = Split(objectandatt, ".")
    if (not ListCount (objectandattlist) = 2) {
      return ("@@@open@@@" + ProcessTextSection(section, data) + "@@@close@@@")
    }
    else {
      objectname = StringListItem(objectandattlist, 0)
      object = ObjectForTextProcessor(objectname)
      if (object = null) {
        return ("@@@open@@@" + ProcessTextSection(section, data) + "@@@close@@@")
      }
      else if (not HasInt (object, StringListItem(objectandattlist, 1))) {
        return ("@@@open@@@" + ProcessTextSection(section, data) + "@@@close@@@")
      }
      else {
        if (Instr(elements, "|") > 0) {
          elementslist = Split(Join(elementslist, ":"), "|")
        }
        index = GetInt(object, StringListItem(objectandattlist, 1))
        if ((0 > index) or (index >= Listcount(elementslist))) {
          return ("@@@open@@@" + ProcessTextSection(section, data) + "@@@close@@@")
        }
        else {
          return (ProcessTextSection(ListItem(elementslist, index), data))
        }
      }
    }
  ]]></function>
  <function name="SetFramePicture" parameters="filename"><![CDATA[
    JS.setPanelContents ("<img src=\"" + GetFileURL(filename) + "\" onload=\"setPanelHeight()\"/>")
    game.panelcontents = filename
  ]]></function>
  <function name="ClearFramePicture">
    JS.setPanelContents ("")
    game.panelcontents = null
  </function>
  <function name="ClearScreen">
    JS.clearScreen ()
  </function>
  <function name="SetForegroundColour" parameters="colour">
    // request (Foreground, colour)
    game.defaultforeground = colour
  </function>
  <function name="SetBackgroundColour" parameters="colour">
    JS.setBackground (colour)
    game.defaultbackground = colour
  </function>
  <function name="SetLinkForegroundColour" parameters="colour">
    // request (LinkForeground, colour)
    game.defaultlinkforeground = colour
  </function>
  <function name="SetFontName" parameters="font">
    game.defaultfont = font
    game.defaultwebfont = ""
  </function>
  <function name="SetWebFontName" parameters="font">
    AddExternalStylesheet ("https://fonts.googleapis.com/css?family=" + Replace(font, " ", "+"))
    game.defaultwebfont = font
  </function>
  <function name="AddExternalStylesheet" parameters="stylesheet">
    if (game.externalstylesheets = null) {
      game.externalstylesheets = NewStringList()
    }
    if (not ListContains(game.externalstylesheets, stylesheet)) {
      list add (game.externalstylesheets, stylesheet)
      JS.addExternalStylesheet (stylesheet)
    }
  </function>
  <function name="SetFontSize" parameters="size">
    game.defaultfontsize = size
  </function>
  <function name="PrintCentered" parameters="text">
    SetAlignment ("center")
    msg (text)
    SetAlignment ("left")
  </function>
  <function name="ShowYouTube" parameters="id">
    JS.AddYouTube (id)
  </function>
  <function name="ShowVimeo" parameters="id">
    JS.AddVimeo (id)
  </function>
  <function name="DisplayHttpLink" parameters="text, url, https"><![CDATA[
    pos = Instr(url, "://")
    if (pos > 0) {
      url = Mid(url, pos + 3)
    }
    if (https) {
      url = "https://" + url
    }
    else {
      url = "http://" + url
    }
    msg ("<a style=\"" + GetCurrentLinkTextFormat() + "\" href=\"" + url + "\">" + text + "</a>")
  ]]></function>
  <function name="DisplayMailtoLink" parameters="text, url"><![CDATA[
    if (Instr(url, "mailto:") = 0) {
      url = "mailto:" + url
    }
    msg ("<a style=\"" + GetCurrentLinkTextFormat() + "\" href=\"" + url + "\">" + text + "</a>")
  ]]></function>
  <function name="CommandLink" parameters="cmd, text" type="string">
    return ("{command:" + cmd + ":" + text + "}")
  </function>
  <function name="Log" parameters="text">
    if (not TypeOf (text) = "string") {
      text = "[" + TypeOf(text) + "]"
    }
    request (Log, text)
    if (GetBoolean(game, "writelogtofile")) {
      text = Replace(text, "\"", "''")
      JS.WriteToLog (text)
    }
  </function>
  <function name="SetBackgroundImage" parameters="filename">
    JS.SetBackgroundImage (GetFileURL(filename))
    game.backgroundimage = filename
  </function>
  <function name="SetBackgroundOpacity" parameters="opacity">
    JS.SetBackgroundOpacity (opacity)
    game.backgroundopacity = opacity
    game.setbackgroundopacity = true
  </function>
  <function name="DisplayList" parameters="list, numbers"><![CDATA[
    if (numbers) {
      result = "<ol>"
    }
    else {
      result = "<ul>"
    }
    foreach (item, list) {
      result = result + "<li>" + item + "</li>"
    }
    if (numbers) {
      result = result + "</ol>"
    }
    else {
      result = result + "</ul>"
    }
    msg (result)
  ]]></function>
  <function name="SetAlignment" parameters="align">
    JS.createNewDiv (align)
  </function>
  <function name="GetCurrentFontFamily" type="string">
    if (game.defaultwebfont = null) {
      return (game.defaultfont)
    }
    else {
      if (game.defaultwebfont = "") {
        return (game.defaultfont)
      }
      else {
        return ("'" + game.defaultwebfont + "', " + game.defaultfont)
      }
    }
  </function>
  <function name="FormatList" parameters="list, joiner, lastjoiner, nothing" type="string"><![CDATA[
    if (ListCount (list) = 0) {
      return (nothing)
    }
    else {
      result = ""
      count = 0
      listLength = ListCount(list)
      foreach (item, list) {
        if (TypeOf(item) = "object") {
          result = result + GetDisplayName(item)
        }
        else {
          result = result + item
        }
        count = count + 1
        if (count = listLength - 1) {
          if (not IsRegexMatch("^\\W", lastjoiner)) {
            result = result + " "
          }
          result = result + lastjoiner + " "
        }
        else if (count < listLength) {
          result = result + joiner + " "
        }
      }
      return (Trim (result))
    }
  ]]></function>
  <function name="Spaces" parameters="number" type="string"><![CDATA[
    game.command_successful = True
    text = ""
    for (x, 1, number) {
      text = text+ "&nbsp;"
    }
    return (text)
  ]]></function>
  <function name="ToRoman" parameters="n" type="string"><![CDATA[
    if (not TypeOf(n) = "int") {
      error ("ToRoman can only handle ints")
    }
    arabic = Split("1000;900;500;400;100;90;50;40;10;9;5;4;1", ";")
    roman = Split("M;CM;D;CD;C;XC;L;XL;X;IX;V;IV;I", ";")
    result = ""
    for (i, 0, 12) {
      a = ToInt(StringListItem(arabic, i))
      r = StringListItem(roman, i)
      while (n >= a) {
        result = result + r
        n = n - a
      }
    }
    return (result)
  ]]></function>
  <function name="Grid_SetScale" parameters="scale">
    JS.Grid_SetScale (scale)
  </function>
  <function name="Grid_CalculateMapCoordinates" parameters="room, playerobject"><![CDATA[
    if (room.parent <> null) {
      if (room.grid_parent_offset_auto) {
        room.grid_parent_offset_x = (room.parent.grid_width - room.grid_width) /2.0
        room.grid_parent_offset_y = (room.parent.grid_length - room.grid_length) /2.0
      }
      Grid_SetGridCoordinateForPlayer (playerobject, room.parent, "x", Grid_GetGridCoordinateForPlayer(playerobject, room, "x") - room.grid_parent_offset_x)
      Grid_SetGridCoordinateForPlayer (playerobject, room.parent, "y", Grid_GetGridCoordinateForPlayer(playerobject, room, "y") - room.grid_parent_offset_y)
      Grid_SetGridCoordinateForPlayer (playerobject, room.parent, "z", Grid_GetGridCoordinateForPlayer(playerobject, room, "z"))
      room.parent.grid_render = true
      Grid_CalculateMapCoordinates (room.parent, playerobject)
    }
    // go through all exits in room, set x,y co-ordinates for the rooms they point to
    foreach (exit, AllExits()) {
      if (exit.parent = room and not GetBoolean(exit, "lookonly")) {
        if (DoesInherit(exit, "northdirection")) {
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "x", Grid_GetGridCoordinateForPlayer(playerobject, room, "x") + room.grid_width/2.0 + exit.grid_offset_x)
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "y", Grid_GetGridCoordinateForPlayer(playerobject, room, "y") + exit.grid_offset_y)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "x", Grid_GetGridCoordinateForPlayer(playerobject, exit, "x") - exit.to.grid_width/2.0)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "y", (Grid_GetGridCoordinateForPlayer(playerobject, exit, "y") - exit.to.grid_length) - exit.grid_length)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "z", Grid_GetGridCoordinateForPlayer(playerobject, room, "z"))
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "end_x", Grid_GetGridCoordinateForPlayer(playerobject, exit, "x"))
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "end_y", Grid_GetGridCoordinateForPlayer(playerobject, exit, "y") - exit.grid_length)
          exit.grid_render = true
          exit.to.grid_render = true
        }
        else if (DoesInherit(exit, "eastdirection")) {
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "x", Grid_GetGridCoordinateForPlayer(playerobject, room, "x") + room.grid_width + exit.grid_offset_x)
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "y", Grid_GetGridCoordinateForPlayer(playerobject, room, "y") + room.grid_length/2.0 + exit.grid_offset_y)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "x", Grid_GetGridCoordinateForPlayer(playerobject, exit, "x") + exit.grid_length)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "y", Grid_GetGridCoordinateForPlayer(playerobject, exit, "y") - exit.to.grid_length/2.0)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "z", Grid_GetGridCoordinateForPlayer(playerobject, room, "z"))
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "end_x", Grid_GetGridCoordinateForPlayer(playerobject, exit, "x") + exit.grid_length)
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "end_y", Grid_GetGridCoordinateForPlayer(playerobject, exit, "y"))
          exit.grid_render = true
          exit.to.grid_render = true
        }
        else if (DoesInherit(exit, "southdirection")) {
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "x", Grid_GetGridCoordinateForPlayer(playerobject, room, "x") + room.grid_width/2.0 + exit.grid_offset_x)
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "y", Grid_GetGridCoordinateForPlayer(playerobject, room, "y") + room.grid_length + exit.grid_offset_y)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "x", Grid_GetGridCoordinateForPlayer(playerobject, exit, "x") - exit.to.grid_width/2.0)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "y", Grid_GetGridCoordinateForPlayer(playerobject, exit, "y") + exit.grid_length)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "z", Grid_GetGridCoordinateForPlayer(playerobject, room, "z"))
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "end_x", Grid_GetGridCoordinateForPlayer(playerobject, exit, "x"))
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "end_y", Grid_GetGridCoordinateForPlayer(playerobject, exit, "y") + exit.grid_length)
          exit.grid_render = true
          exit.to.grid_render = true
        }
        else if (DoesInherit(exit, "westdirection")) {
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "x", Grid_GetGridCoordinateForPlayer(playerobject, room, "x") + exit.grid_offset_x)
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "y", Grid_GetGridCoordinateForPlayer(playerobject, room, "y") + room.grid_length/2.0 + exit.grid_offset_y)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "x", (Grid_GetGridCoordinateForPlayer(playerobject, exit, "x") - exit.to.grid_width) - exit.grid_length)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "y", Grid_GetGridCoordinateForPlayer(playerobject, exit, "y") - exit.to.grid_length/2.0)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "z", Grid_GetGridCoordinateForPlayer(playerobject, room, "z"))
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "end_x", Grid_GetGridCoordinateForPlayer(playerobject, exit, "x") - exit.grid_length)
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "end_y", Grid_GetGridCoordinateForPlayer(playerobject, exit, "y"))
          exit.grid_render = true
          exit.to.grid_render = true
        }
        else if (DoesInherit(exit, "northwestdirection")) {
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "x", Grid_GetGridCoordinateForPlayer(playerobject, room, "x") + exit.grid_offset_x)
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "y", Grid_GetGridCoordinateForPlayer(playerobject, room, "y") + exit.grid_offset_y)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "x", (Grid_GetGridCoordinateForPlayer(playerobject, exit, "x") - exit.to.grid_width) - exit.grid_length)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "y", (Grid_GetGridCoordinateForPlayer(playerobject, exit, "y") - exit.to.grid_length) - exit.grid_length)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "z", Grid_GetGridCoordinateForPlayer(playerobject, room, "z"))
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "end_x", Grid_GetGridCoordinateForPlayer(playerobject, exit, "x") - exit.grid_length)
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "end_y", Grid_GetGridCoordinateForPlayer(playerobject, exit, "y") - exit.grid_length)
          exit.grid_render = true
          exit.to.grid_render = true
        }
        else if (DoesInherit(exit, "northeastdirection")) {
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "x", Grid_GetGridCoordinateForPlayer(playerobject, room, "x") + room.grid_width + exit.grid_offset_x)
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "y", Grid_GetGridCoordinateForPlayer(playerobject, room, "y") + exit.grid_offset_y)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "x", Grid_GetGridCoordinateForPlayer(playerobject, exit, "x") + exit.grid_length)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "y", (Grid_GetGridCoordinateForPlayer(playerobject, exit, "y") - exit.to.grid_length) - exit.grid_length)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "z", Grid_GetGridCoordinateForPlayer(playerobject, room, "z"))
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "end_x", Grid_GetGridCoordinateForPlayer(playerobject, exit, "x") + exit.grid_length)
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "end_y", Grid_GetGridCoordinateForPlayer(playerobject, exit, "y") - exit.grid_length)
          exit.grid_render = true
          exit.to.grid_render = true
        }
        else if (DoesInherit(exit, "southwestdirection")) {
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "x", Grid_GetGridCoordinateForPlayer(playerobject, room, "x") + exit.grid_offset_x)
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "y", Grid_GetGridCoordinateForPlayer(playerobject, room, "y") + room.grid_length + exit.grid_offset_y)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "x", (Grid_GetGridCoordinateForPlayer(playerobject, exit, "x") - exit.to.grid_width) - exit.grid_length)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "y", Grid_GetGridCoordinateForPlayer(playerobject, exit, "y") + exit.grid_length)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "z", Grid_GetGridCoordinateForPlayer(playerobject, room, "z"))
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "end_x", Grid_GetGridCoordinateForPlayer(playerobject, exit, "x") - exit.grid_length)
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "end_y", Grid_GetGridCoordinateForPlayer(playerobject, exit, "y") + exit.grid_length)
          exit.grid_render = true
          exit.to.grid_render = true
        }
        else if (DoesInherit(exit, "southeastdirection")) {
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "x", Grid_GetGridCoordinateForPlayer(playerobject, room, "x") + room.grid_width + exit.grid_offset_x)
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "y", Grid_GetGridCoordinateForPlayer(playerobject, room, "y") + room.grid_length + exit.grid_offset_y)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "x", Grid_GetGridCoordinateForPlayer(playerobject, exit, "x") + exit.grid_length)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "y", Grid_GetGridCoordinateForPlayer(playerobject, exit, "y") + exit.grid_length)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "z", Grid_GetGridCoordinateForPlayer(playerobject, room, "z"))
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "end_x", Grid_GetGridCoordinateForPlayer(playerobject, exit, "x") + exit.grid_length)
          Grid_SetGridCoordinateForPlayer (playerobject, exit, "end_y", Grid_GetGridCoordinateForPlayer(playerobject, exit, "y") + exit.grid_length)
          exit.grid_render = true
          exit.to.grid_render = true
        }
        else if (DoesInherit(exit, "updirection")) {
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "x", Grid_GetGridCoordinateForPlayer(playerobject, room, "x") + room.grid_width/2.0 - exit.to.grid_width/2.0 + exit.grid_offset_x)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "y", Grid_GetGridCoordinateForPlayer(playerobject, room, "y") + room.grid_length/2.0 - exit.to.grid_length/2.0 + exit.grid_offset_y)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "z", Grid_GetGridCoordinateForPlayer(playerobject, room, "z") + exit.grid_length)
          exit.grid_render = false
          exit.to.grid_render = true
        }
        else if (DoesInherit(exit, "downdirection")) {
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "x", Grid_GetGridCoordinateForPlayer(playerobject, room, "x") + room.grid_width/2.0 - exit.to.grid_width/2.0 + exit.grid_offset_x)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "y", Grid_GetGridCoordinateForPlayer(playerobject, room, "y") + room.grid_length/2.0 - exit.to.grid_length/2.0 + exit.grid_offset_y)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "z", Grid_GetGridCoordinateForPlayer(playerobject, room, "z") - exit.grid_length)
          exit.grid_render = false
          exit.to.grid_render = true
        }
        else if (DoesInherit(exit, "indirection") or DoesInherit(exit, "outdirection")) {
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "x", Grid_GetGridCoordinateForPlayer(playerobject, room, "x") + room.grid_width/2.0 - exit.to.grid_width/2.0 + exit.grid_offset_x)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "y", Grid_GetGridCoordinateForPlayer(playerobject, room, "y") + room.grid_length/2.0 - exit.to.grid_length/2.0 + exit.grid_offset_y)
          Grid_SetGridCoordinateForPlayer (playerobject, exit.to, "z", Grid_GetGridCoordinateForPlayer(playerobject, room, "z"))
          exit.grid_render = false
          exit.to.grid_render = true
        }
      }
    }
  ]]></function>
  <function name="Grid_DrawPlayerInRoom" parameters="room">
    if (room.grid_render) {
      Grid_DrawRoom (room, false, game.pov)
      player_x = Grid_GetGridCoordinateForPlayer(game.pov, room, "x") + room.grid_width/2.0
      player_y = Grid_GetGridCoordinateForPlayer(game.pov, room, "y") + room.grid_length/2.0
      player_z = Grid_GetGridCoordinateForPlayer(game.pov, room, "z")
      // Grid_DrawPlayer(x, y, z, radius, border, borderWidth, fill)
      JS.Grid_DrawPlayer (player_x, player_y, player_z, 5, "black", 2, "yellow")
    }
  </function>
  <function name="Grid_DrawRoom" parameters="room, redraw, playerobject"><![CDATA[
    if (room.grid_render) {
      if (redraw or not Grid_GetRoomBooleanForPlayer(playerobject, room, "grid_isdrawn")) {
        if (room.parent <> null) {
          Grid_DrawRoom (room.parent, redraw, playerobject)
        }
        JS.Grid_DrawBox (Grid_GetGridCoordinateForPlayer(game.pov, room, "x"), Grid_GetGridCoordinateForPlayer(game.pov, room, "y"), Grid_GetGridCoordinateForPlayer(game.pov, room, "z"), room.grid_width, room.grid_length, room.grid_border, room.grid_borderwidth, room.grid_fill, room.grid_bordersides)
        if (LengthOf(room.grid_label) > 0) {
          label_x = Grid_GetGridCoordinateForPlayer(game.pov, room, "x") + room.grid_width/2.0
          label_y = (Grid_GetGridCoordinateForPlayer(game.pov, room, "y") + room.grid_length/2.0) - 0.5
          JS.Grid_DrawLabel (label_x, label_y, Grid_GetGridCoordinateForPlayer(game.pov, room, "z"), room.grid_label, room.grid_label_colour)
        }
        foreach (exit, AllExits()) {
          if (exit.grid_render and exit.parent = room and exit.grid_length > 0) {
            Grid_DrawLine (Grid_GetGridCoordinateForPlayer(game.pov, exit, "x"), Grid_GetGridCoordinateForPlayer(game.pov, exit, "y"), Grid_GetGridCoordinateForPlayer(game.pov, exit, "end_x"), Grid_GetGridCoordinateForPlayer(game.pov, exit, "end_y"), game.mapexitcolour, game.mapexitwidth)
          }
        }
        Grid_SetRoomBooleanForPlayer (playerobject, room, "grid_isdrawn", true)
      }
    }
  ]]></function>
  <function name="Grid_ShowCustomLayer" parameters="visible">
    if (visible) {
      JS.Grid_ShowCustomLayer (true)
    }
    else {
      JS.Grid_ShowCustomLayer (false)
    }
  </function>
  <function name="Grid_ClearCustomLayer">
    JS.Grid_ClearCustomLayer ()
  </function>
  <function name="Grid_DrawLine" parameters="x1, y1, x2, y2, border, borderWidth">
    JS.Grid_DrawLine (x1, y1, x2, y2, border, borderWidth)
  </function>
  <function name="Grid_DrawArrow" parameters="id, x1, y1, x2, y2, border, borderWidth">
    JS.Grid_DrawArrow (id, x1, y1, x2, y2, border, borderWidth)
  </function>
  <function name="Grid_DrawGridLines" parameters="x1, y1, x2, y2, border">
    JS.Grid_DrawGridLines (x1, y1, x2, y2, border)
  </function>
  <function name="Grid_SetCentre" parameters="x, y">
    JS.Grid_SetCentre (x, y)
  </function>
  <function name="Grid_DrawSquare" parameters="id, x, y, width, height, text, fill">
    JS.Grid_DrawSquare (id, x, y, width, height, text, fill)
  </function>
  <function name="Grid_LoadSvg" parameters="data, id">
    JS.Grid_LoadSvg (data, id)
  </function>
  <function name="Grid_DrawSvg" parameters="id, symbolid, x, y, width, height">
    JS.Grid_DrawSvg (id, symbolid, x, y, width, height)
  </function>
  <function name="Grid_DrawImage" parameters="id, url, x, y, width, height">
    JS.Grid_DrawImage (id, url, x, y, width, height)
  </function>
  <function name="Grid_AddNewShapePoint" parameters="x, y">
    JS.Grid_AddNewShapePoint (x, y)
  </function>
  <function name="Grid_DrawShape" parameters="id, border, fill, opacity">
    JS.Grid_DrawShape (id, border, fill, opacity)
  </function>
  <function name="JS_GridSquareClick" parameters="parameterstring">
    parameters = Split(parameterstring, ";")
    x = ToInt(StringListItem(parameters, 0))
    y = ToInt(StringListItem(parameters, 1))
    GridSquareClick (x, y)
  </function>
  <function name="GridSquareClick" parameters="x, y">
    // Copy this function into your game to handle grid square clicks
  </function>
  <function name="Grid_Redraw">
    foreach (object, AllObjects()) {
      if (Grid_GetRoomBooleanForPlayer(game.pov, object, "grid_isdrawn")) {
        Grid_DrawRoom (object, true, game.pov)
      }
    }
  </function>
  <function name="Grid_SetGridCoordinateForPlayer" parameters="playerobject, room, coordinate, value">
    coordinates = Grid_GetPlayerCoordinatesForRoom(playerobject, room)
    if (DictionaryContains(coordinates, coordinate)) {
      dictionary remove (coordinates, coordinate)
    }
    dictionary add (coordinates, coordinate, value * 1.0)
  </function>
  <function name="Grid_GetGridCoordinateForPlayer" parameters="playerobject, room, coordinate" type="double">
    coordinates = Grid_GetPlayerCoordinatesForRoom(playerobject, room)
    return (DictionaryItem(coordinates, coordinate))
  </function>
  <function name="Grid_SetRoomBooleanForPlayer" parameters="playerobject, room, coordinate, value">
    datadictionary = Grid_GetPlayerCoordinatesForRoom(playerobject, room)
    if (DictionaryContains(datadictionary, coordinate)) {
      dictionary remove (datadictionary, coordinate)
    }
    dictionary add (datadictionary, coordinate, value)
  </function>
  <function name="Grid_GetRoomBooleanForPlayer" parameters="playerobject, room, attribute" type="boolean">
    coordinatedata = Grid_GetPlayerCoordinateDictionary(playerobject)
    if (not DictionaryContains(coordinatedata, room.name)) {
      return (false)
    }
    else {
      datadictionary = Grid_GetPlayerCoordinatesForRoom(playerobject, room)
      if (DictionaryContains(datadictionary, attribute)) {
        return (DictionaryItem(datadictionary, attribute))
      }
      else {
        return (false)
      }
    }
  </function>
  <function name="Grid_GetPlayerCoordinateDictionary" parameters="playerobject" type="dictionary">
    if (HasAttribute(playerobject, "grid_coordinates_delegate")) {
      return (Grid_GetPlayerCoordinateDictionary(playerobject.grid_coordinates_delegate))
    }
    else {
      if (not HasAttribute(playerobject, "grid_coordinates")) {
        playerobject.grid_coordinates = NewDictionary()
        Grid_SetGridCoordinateForPlayer (playerobject, playerobject.parent, "x", 0)
        Grid_SetGridCoordinateForPlayer (playerobject, playerobject.parent, "y", 0)
        Grid_SetGridCoordinateForPlayer (playerobject, playerobject.parent, "z", 0)
        playerobject.parent.grid_render = true
        Grid_CalculateMapCoordinates (playerobject.parent, playerobject)
      }
      return (playerobject.grid_coordinates)
    }
  </function>
  <function name="Grid_GetPlayerCoordinatesForRoom" parameters="playerobject, room" type="dictionary">
    coordinatedata = Grid_GetPlayerCoordinateDictionary(playerobject)
    if (not DictionaryContains(coordinatedata, room.name)) {
      dictionary add (coordinatedata, room.name, NewDictionary())
    }
    return (DictionaryItem(coordinatedata, room.name))
  </function>
  <function name="MergePOVCoordinates"><![CDATA[
    coordinateowner = GetCoordinateOwner(game.pov)
    foreach (obj, GetDirectChildren(game.pov.parent)) {
      if (obj <> game.pov and HasAttribute(obj, "grid_coordinates")) {
        objcoordinateowner = GetCoordinateOwner(obj)
        if (coordinateowner <> objcoordinateowner) {
          MapPOVCoordinates (objcoordinateowner, coordinateowner)
        }
      }
    }
  ]]></function>
  <function name="GetCoordinateOwner" parameters="playerobject" type="object">
    if (HasAttribute(playerobject, "grid_coordinates_delegate")) {
      return (GetCoordinateOwner(playerobject.grid_coordinates_delegate))
    }
    else {
      return (playerobject)
    }
  </function>
  <function name="MapPOVCoordinates" parameters="source, target">
    sourcecoordinates = Grid_GetPlayerCoordinateDictionary(source)
    targetcoordinates = Grid_GetPlayerCoordinateDictionary(target)
    xoffset = Grid_GetGridCoordinateForPlayer(target, game.pov.parent, "x") - Grid_GetGridCoordinateForPlayer(source, game.pov.parent, "x")
    yoffset = Grid_GetGridCoordinateForPlayer(target, game.pov.parent, "y") - Grid_GetGridCoordinateForPlayer(source, game.pov.parent, "y")
    zoffset = Grid_GetGridCoordinateForPlayer(target, game.pov.parent, "z") - Grid_GetGridCoordinateForPlayer(source, game.pov.parent, "z")
    foreach (roomname, sourcecoordinates) {
      coordinatedata = DictionaryItem(sourcecoordinates, roomname)
      if (not DictionaryContains(targetcoordinates, roomname)) {
        newroomdata = NewDictionary()
        dictionary add (targetcoordinates, roomname, newroomdata)
        MapPOVCoordinate (coordinatedata, newroomdata, "x", xoffset)
        MapPOVCoordinate (coordinatedata, newroomdata, "y", yoffset)
        MapPOVCoordinate (coordinatedata, newroomdata, "z", zoffset)
        MapPOVCoordinate (coordinatedata, newroomdata, "end_x", xoffset)
        MapPOVCoordinate (coordinatedata, newroomdata, "end_y", yoffset)
      }
      else {
        newroomdata = DictionaryItem(targetcoordinates, roomname)
      }
      if (DictionaryContains(coordinatedata, "grid_isdrawn")) {
        if (DictionaryContains(newroomdata, "grid_isdrawn")) {
          dictionary remove (newroomdata, "grid_isdrawn")
        }
        dictionary add (newroomdata, "grid_isdrawn", DictionaryItem(coordinatedata, "grid_isdrawn"))
      }
    }
    source.grid_coordinates_delegate = target
    Grid_Redraw
    Grid_DrawPlayerInRoom (game.pov.parent)
  </function>
  <function name="MapPOVCoordinate" parameters="sourcedata, targetdata, name, offset">
    if (DictionaryContains(sourcedata, name)) {
      value = DictionaryItem(sourcedata, name)
      dictionary add (targetdata, name, value + offset)
    }
  </function>
  <function name="DiceRoll" parameters="dice" type="int"><![CDATA[
    if (TypeOf(dice) = "int") {
      return (dice)
    }
    p1 = Instr(dice, "d")
    p2 = Instr(dice, "+")
    p4 = Instr(dice, "-")
    p3 = LengthOf(dice)
    if (p1 = 0) {
      if (IsInt(dice)) {
        return (ToInt(dice))
      }
      error ("Invalid dice type: " + dice)
    }
    number_str = Mid(dice, 1, p1 - 1)
    if (LengthOf(number_str) = 0) {
      number = 1
    }
    else {
      number = ToInt(number_str)
    }
    if (p2 > 0) {
      sides = ToInt(Mid(dice, p1 + 1, p2 - p1 - 1))
      total = ToInt(Mid(dice, p2 + 1, p3 - p2))
    }
    else if (p4 > 0) {
      sides = ToInt(Mid(dice, p1 + 1, p4 - p1 - 1))
      total = -ToInt(Mid(dice, p4 + 1, p3 - p2))
    }
    else {
      sides = ToInt(Mid(dice, p1 + 1, p3 - p1))
      total = 0
    }
    for (i, 1, number) {
      total = total + GetRandomInt(1, sides)
    }
    return (total)
  ]]></function>
  <function name="PickOneObject" parameters="lst" type="object">
    n = ListCount(lst)
    if (n = 0) {
      return (null)
    }
    index = GetRandomInt(0, n - 1)
    return (ObjectListItem(lst, index))
  </function>
  <function name="PickOneString" parameters="lst" type="string">
    if (TypeOf(lst) = "string") {
      lst = Split(lst, ";")
    }
    n = ListCount(lst)
    if (n = 0) {
      return ("")
    }
    index = GetRandomInt(0, n - 1)
    return (StringListItem(lst, index))
  </function>
  <function name="PickOneChild" parameters="obj" type="object">
    return (PickOneObject(GetDirectChildren(obj)))
  </function>
  <function name="PickOneChildOfType" parameters="room, typename" type="object">
    l = NewObjectList()
    foreach (o, GetDirectChildren(room)) {
      if (DoesInherit(o, typename)) {
        list add (l, o)
      }
    }
    return (PickOneObject(l))
  </function>
  <function name="PickOneExit" parameters="room" type="object">
    return (PickOneObject(ScopeExitsForRoom (room)))
  </function>
  <function name="PickOneUnlockedExit" parameters="room" type="object">
    return (PickOneObject(ScopeUnlockedExitsForRoom (room)))
  </function>
  <function name="TextFX_Typewriter" parameters="text, speed">
    TextFX_Typewriter_Internal (text, speed, GetCurrentFontFamily(), game.defaultforeground, game.defaultfontsize)
  </function>
  <function name="TextFX_Typewriter_Internal" parameters="text, speed, font, color, size">
    JS.TextFX.Typewriter (text, speed, font, color, size)
  </function>
  <function name="TextFX_Unscramble" parameters="text, speed, reveal">
    TextFX_Unscramble_Internal (text, speed, reveal, GetCurrentFontFamily(), game.defaultforeground, game.defaultfontsize)
  </function>
  <function name="TextFX_Unscramble_Internal" parameters="text, speed, reveal, font, color, size">
    JS.TextFX.Unscramble (text, speed, reveal, font, color, size)
  </function>
  <function name="_DoWear" parameters="object" type="boolean"><![CDATA[
    // Is this possible?
    if (not HasAttribute(object,"worn") or not HasAttribute(object,"wear_slots")) {
      // No, not a garment
      msg (DynamicTemplate("WearUnsuccessful", object))
      return (false)
    }
    if (object.parent = game.pov and object.worn = true) {
      // No, already worn
      msg (DynamicTemplate("AlreadyWearing", object))
      return (false)
    }
    if (not ListContains(ScopeInventory(), object)) {
      // No, not held
      msg (DynamicTemplate("CannotWearIfNotHeld", object))
      return (false)
    }
    // Are other worn garments in the way?
    obj = _GetOuterForGarment(game.pov, object)
    if (not obj = null) {
      if (obj.wear_layer > object.wear_layer or obj.wear_layer = 0 or object.wear_layer = 0) {
        msg (DynamicTemplate("CannotWearOver", obj))
        return (false)
      }
      if (obj.wear_layer = object.wear_layer) {
        msg (DynamicTemplate("CannotWearWith", obj))
        return (false)
      }
    }
    if (not TestGarment(object)) {
      return (false)
    }
    WearGarment (object)
    if (object.wearmsg = null) {
      P (DynamicTemplate("WearSuccessful",object))
    }
    else {
      P (object.wearmsg)
    }
    // do after
    if (HasScript(object, "onafterwear")) {
      do (object, "onafterwear")
    }
    else if (HasString(object, "onafterwear")) {
      P (object.onafterwear)
    }
    AfterWear
    return (true)
  ]]></function>
  <function name="WearGarment" parameters="object">
    if (GetBoolean(object, "multistate")) {
      object.multistate_status = 1
    }
    else {
      object.multistate_status = 0
    }
    if (object.alias = null) {
      object.alias = object.name
    }
    if (object.listalias = null) {
      object.listalias = object.alias
    }
    if (object.original_alias = null) {
      object.original_drop = object.drop
      object.original_alias = object.alias
      object.original_listalias = object.listalias
      object.original_bonusatts = object.bonusatts
      object.original_wearslots = object.wear_slots
      object.display = GetDisplayAlias(object)
    }
    object.parent = _GetWornClothingLocation()
    object.worn = True
    object.drop = false
    _SetGarmentAlias (object)
    _SetMultistate (object)
    SetVerbs
    SetBonuses (object, true)
    if (HasInt(game.pov, "maxobjects")) {
      game.pov.maxobjects = game.pov.maxobjects + 1
    }
    // Do error checking now so item can be put on even if multistate is going to fail
    if (GetBoolean(object, "multistate")) {
      if (not HasAttribute(object, "multistate_descriptors")) {
        error ("No descriptors for multistate clothing: " + object.name)
      }
      if (not HasAttribute(object, "multistate_verbs")) {
        error ("No verbs for multistate clothing: " + object.name)
      }
      if (not HasAttribute(object, "multistate_wearslots")) {
        error ("No wearslots for multistate clothing: " + object.name)
      }
      statecount = ListCount(object.multistate_descriptors)
      if (not statecount = ListCount(object.multistate_verbs)) {
        error ("Mismatch in lists for multistate clothing: " + object.name)
      }
      if (not statecount = ListCount(object.multistate_wearslots)) {
        error ("Mismatch in lists for multistate clothing: " + object.name)
      }
      object.original_wearslots = object.wear_slots
    }
  </function>
  <function name="_DoRemove" parameters="object" type="boolean"><![CDATA[
    if (not ListContains(GetAllChildObjects(game.pov), object)) {
      msg (DynamicTemplate("CannotRemoveIfNotHeld", object))
      return (false)
    }
    if (not GetBoolean(object, "worn")) {
      msg (DynamicTemplate("CannotRemoveIfNotWearing", object))
      return (false)
    }
    if (not GetBoolean(object, "removeable")) {
      if (HasString(object, "notremoveablemessage")) {
        msg (object.notremoveablemessage)
      }
      else {
        msg (DynamicTemplate("NotRemovable", object))
      }
      return (false)
    }
    if (HasInt(game.pov, "maxobjects")) {
      if (ListCount(GetAllChildObjects(game.pov)) >= game.pov.maxobjects) {
        msg (DynamicTemplate("MaxObjectsInInventory", object))
        return (false)
      }
    }
    obj = _GetOuterForGarment(game.pov, object)
    if (not obj = null) {
      if (obj.wear_layer > object.wear_layer) {
        msg (DynamicTemplate("RemoveFirst", obj))
        return (false)
      }
    }
    if (not TestRemove(object)) {
      return (false)
    }
    RemoveGarment (object)
    if (object.removemsg = null) {
      P (DynamicTemplate("RemoveSuccessful",object))
    }
    else {
      P (object.removemsg)
    }
    // do after
    if (HasScript(object, "onafterremove")) {
      do (object, "onafterremove")
    }
    else if (HasString(object, "onafterremove")) {
      P (object.onafterremove)
    }
    AfterRemove
    return (true)
  ]]></function>
  <function name="RemoveGarment" parameters="object"><![CDATA[
    SetBonuses (object, false)
    object.worn = false
    object.drop = object.original_drop
    object.alias = object.original_alias
    object.multistate_status = 0
    if (HasString(object, "listalias")) {
      if (StartsWith(object.listalias, "<span style=\"color:blue\">")) {
        object.listalias = null
        do (object, "colourmylistalias")
      }
      else {
        object.listalias = object.original_listalias
      }
    }
    object.parent = game.pov
    if (HasInt(game.pov, "maxobjects")) {
      game.pov.maxobjects = game.pov.maxobjects - 1
    }
    SetVerbs
  ]]></function>
  <function name="Slots" type="stringlist">
    sl = NewStringList()
    foreach (o, AllObjects()) {
      if (HasAttribute(o, "wear_slots")) {
        foreach (s, o.wear_slots) {
          if (not ListContains(sl, s)) {
            list add (sl, s)
          }
        }
      }
    }
    return (sl)
  </function>
  <function name="GetDisplayGarment" parameters="obj" type="string"><![CDATA[
    if (not GetBoolean(obj, "usedefaultprefix")) {
      if (obj.prefix = null) {
        prefix = ""
      }
      else {
        prefix = obj.prefix
      }
    }
    else {
      prefix = GetDefaultPrefix(obj)
    }
    if (LengthOf(prefix) > 0) {
      prefix = prefix + " "
    }
    if (HasString(obj, "original_alias")) {
      result = prefix + obj.original_alias
    }
    else {
      result = prefix + obj.alias
    }
    if (not GetBoolean(obj, "usedefaultprefix") and HasString(obj, "suffix")) {
      if (LengthOf(obj.suffix) > 0) {
        result = result + " " + obj.suffix
      }
    }
    return (result)
  ]]></function>
  <function name="GetDescriptor" parameters="object" type="string">
    if (object.multistate_status = 0) {
      return (" (" + object.wornmodifier + ")")
    }
    s = StringListItem(object.multistate_descriptors, object.multistate_status - 1)
    if (s = "*") {
      return (" (" + object.wornmodifier + ")")
    }
    return (" (" + object.wornmodifier + " " + s + ")")
  </function>
  <function name="SetMultistate" parameters="object, state"><![CDATA[
    if (state < 1) {
      error ("Attempt to set state to " + state + " for " + object.name)
    }
    if (state > ListCount(object.multistate_descriptors)) {
      error ("Attempt to set state to " + state + " for " + object.name + " (max " + ListCount(object.multistate_descriptors) + ")")
    }
    if (not object.multistate_status = state) {
      SetBonuses (object, false)
      object.multistate_status = state
      _SetGarmentAlias (object)
      _SetMultistate (object)
      SetBonuses (object, true)
      SetVerbs
    }
  ]]></function>
  <function name="GetOuterFor" parameters="char, slot" type="object"><![CDATA[
    garment = null
    foreach (o, _GetList(char, slot)) {
      if (garment = null) {
        garment = o
      }
      else if (o.wear_layer > garment.wear_layer) {
        garment = o
      }
    }
    return (garment)
  ]]></function>
  <function name="ListWornFor" parameters="char" type="objectlist">
    return (_GetList(char, null))
  </function>
  <function name="ListVisibleFor" parameters="char" type="objectlist">
    ol = newObjectList()
    foreach (s, Slots()) {
      o = GetOuterFor(char, s)
      if (not o = null and not ListContains(ol, o)) {
        list add (ol, o)
      }
    }
    return (ol)
  </function>
  <function name="GetArmourFor" parameters="char" type="int">
    total = 2 * _GetSlotArmour(char, "head") + 3 * _GetSlotArmour(char, "torso")
    foreach (s, Split("feet|legs|shoulders|arms|hands", "|")) {
      total = total + _GetSlotArmour(char, s)
    }
    return (total)
  </function>
  <function name="GetOuter" parameters="slot" type="object">
    return (GetOuterFor(game.pov, slot))
  </function>
  <function name="GetArmour" type="int">
    return (GetArmourFor(game.pov))
  </function>
  <function name="SetVerbs">
    foreach (o, GetAllChildObjects(game.pov)) {
      if (DoesInherit(o, "wearable")) {
        if (HasAttribute(o, "wear_adjverbs")) {
          if (o.wear_adjverbs) {
            if (HasAttribute(o, "wear_slots") and HasInt(o, "wear_layer")) {
              _SetVerbsForGarment (o)
            }
            if (not HasString(o, "alias")) {
              o.alias = o.name
            }
            if (not HasString(o, "listalias")) {
              o.listalias = o.alias
            }
          }
        }
      }
    }
  </function>
  <function name="WornCount" type="int">
    count = 0
    foreach (o, GetAllChildObjects(game.pov)) {
      if (GetBoolean(o, "worn")) {
        count = count + 1
      }
    }
    return (count)
  </function>
  <function name="ListClothes" type="string">
    l = NewStringList()
    foreach (obj, ListWornFor(game.pov)) {
      list add (l, GetDisplayGarment(obj))
    }
    return (FormatList(l, ",", "and", "nothing"))
  </function>
  <function name="SetBonuses" parameters="garment, wearflag">
    if (HasString(garment, "bonusatts")) {
      foreach (att, Split(garment.bonusatts, ";")) {
        bonus = 1
        plusarray = Split(att, "+")
        minusarray = Split(att, "-")
        if (ListCount(plusarray) = 2) {
          att = StringListitem(plusarray, 0)
          if (not IsInt(StringListitem(plusarray, 1))) {
            error ("Bonus attribute for " + garment.name + " not properly formatted: " + garment.bonusatts)
          }
          bonus = ToInt(StringListitem(plusarray, 1))
        }
        if (ListCount(minusarray) = 2) {
          att = StringListitem(minusarray, 0)
          if (not IsInt(StringListitem(minusarray, 1))) {
            error ("Negative bonus attribute for " + garment.name + " not properly formatted: " + garment.bonusatts)
          }
          bonus = -ToInt(StringListitem(minusarray, 1))
        }
        if (not wearflag) {
          bonus = -bonus
        }
        bonus = ClothingBonusMultiplier() * bonus
        n = GetInt(game.pov, att) + bonus
        set (game.pov, att, n)
      }
    }
  </function>
  <function name="SetAlias" parameters="object, alias">
    SetListAlias (object, alias, alias)
  </function>
  <function name="SetListAlias" parameters="object, alias, listalias">
    object.alias = alias
    object.listalias = listalias
    if (Equal(object.worn, true)) {
      object.original_alias = object.alias
      object.original_listalias = object.listalias
      object.display = GetDisplayAlias(object)
      _SetGarmentAlias (object)
    }
  </function>
  <function name="_SetMultistate" parameters="object">
    if (GetBoolean(object, "multistate")) {
      ws = StringListItem(object.multistate_wearslots, object.multistate_status - 1)
      if (ws = "*") {
        object.wear_slots = object.original_wearslots
      }
      else {
        object.wear_slots = Split(ws, ";")
      }
      wv = StringListItem(object.multistate_verbs, object.multistate_status - 1)
      if (wv = "*") {
        object.wornverbs = null
      }
      else {
        object.wornverbs = wv
      }
      ba = StringListItem(object.multistate_bonusatts, object.multistate_status - 1)
      if (ba = "*") {
        object.bonusatts = object.original_bonusatts
      }
      else {
        object.bonusatts = ba
      }
    }
  </function>
  <function name="_SetGarmentAlias" parameters="object"><![CDATA[
    ext = GetDescriptor(object)
    object.alias = object.display + ext
    if (HasString(object, "listalias")) {
      if (StartsWith(object.listalias, "<span style=\"color:blue\">")) {
        object.listalias = null
        do (object, "colourmylistalias")
      }
      else {
        object.listalias = object.original_listalias + ext
      }
    }
  ]]></function>
  <function name="_GetWornClothingLocation" type="object">
    foreach (o, GetDirectChildren(game.pov)) {
      if (GetBoolean(o, "wornclothinglocation")) {
        return (o)
      }
    }
    return (game.pov)
  </function>
  <function name="_GetOuterForGarment" parameters="char, garment" type="object">
    foreach (slot, garment.wear_slots) {
      obj = GetOuterFor(char, slot)
      if (not obj = null and not obj = garment) {
        return (obj)
      }
    }
    return (null)
  </function>
  <function name="_SetVerbList" parameters="garment, list, s">
    garment.inventoryverbs = list
    if (not s = null) {
      if (not s = "") {
        foreach (s2, Split(s, ";")) {
          list add (garment.inventoryverbs, s2)
        }
      }
    }
  </function>
  <function name="_SetVerbsForGarment" parameters="garment"><![CDATA[
    outer = _GetOuterForGarment(game.pov, garment)
    if (not garment.worn) {
      if (outer = null) {
        _SetVerbList (garment, Split("Look at;Drop;Wear", ";"), garment.invverbs)
      }
      else if (outer.wear_layer < garment.wear_layer) {
        _SetVerbList (garment, Split("Look at;Drop;Wear", ";"), garment.invverbs)
      }
      else {
        _SetVerbList (garment, Split("Look at;Drop", ";"), garment.invverbs)
      }
    }
    else {
      if (outer = null) {
        if (garment.removeable) {
          _SetVerbList (garment, Split("Look at;Remove", ";"), garment.wornverbs)
        }
        else {
          _SetVerbList (garment, Split("Look at", ";"), garment.wornverbs)
        }
      }
      else if (outer.wear_layer < garment.wear_layer) {
        if (garment.removeable) {
          _SetVerbList (garment, Split("Look at;Remove", ";"), garment.wornverbs)
        }
        else {
          _SetVerbList (garment, Split("Look at", ";"), garment.wornverbs)
        }
      }
      else {
        garment.inventoryverbs = Split("Look at", ";")
      }
    }
  ]]></function>
  <function name="_GetList" parameters="char, slot" type="objectlist">
    garments = NewObjectList()
    foreach (o, GetAllChildObjects(char)) {
      if (HasAttribute(o, "wear_slots") and HasInt(o, "wear_layer") and GetBoolean(o, "worn")) {
        if (ListContains(o.wear_slots, slot) or slot = null) {
          list add (garments, o)
        }
      }
    }
    return (garments)
  </function>
  <function name="_GetSlotArmour" parameters="char, slot" type="int"><![CDATA[
    total = 0
    max = 0
    foreach (o, _GetList(char, slot)) {
      total = total + o.armour
      if (o.armour > max) {
        max = o.armour
      }
    }
    return (total + max)
  ]]></function>
  <function name="ClothingBonusMultiplier" type="int">
    return (1)
  </function>
  <function name="AfterRemove">
  </function>
  <function name="AfterWear">
  </function>
  <function name="P" parameters="s">
    msg (s)
  </function>
  <function name="UpdateArmour">
  </function>
  <function name="TestGarment" parameters="object" type="boolean">
    if (HasString(game.pov, "notallowedtodress")) {
      msg (game.pov.notallowedtotake)
      return (false)
    }
    else {
      return (true)
    }
  </function>
  <function name="TestRemove" parameters="object" type="boolean">
    if (HasString(game.pov, "notallowedtoundress")) {
      msg (game.pov.notallowedtotake)
      return (false)
    }
    else {
      return (true)
    }
  </function>
  <function name="ParseToQuestCode" parameters="text"><![CDATA[
    // ----------------------------------------------------------------------------------------------------
    // REGEX
    // the regular expression to check the user input.
    // RegEx available in https://regex101.com/r/4qBEbT/1
    // ----------------------------------------------------------------------------------------------------
    regex = "^(?<object>\\S+?)\\.(?<attribute>\\S+?)(?:(?<keytoken>\\[|\\{)(?<key>.*?)(?:\\]|\\}))?(?:\\s?(?<istoken>\\=)\\s?(?:(?<valkeytoken>(?:\\[|\\{)?)(?<value>.*?)(?:\\]|\\})?)(?(valkeytoken)|(?:(?<valobject>.+?)\\.(?<valattribute>.+?))))?$"
    // ----------------------------------------------------------------------------------------------------
    // SUCCESS MATCH
    // If the user's entry is error-free, it is validated further.
    // ----------------------------------------------------------------------------------------------------
    if (IsRegexMatch (regex, text)) {
      result = populate (regex, text)
      Log (ToString(result))
      // ----------------------------------------------------------------------------------------------------
      // ASSIGN RESULT
      // Assign the result of the match to the appropriate object and attribute.
      // ----------------------------------------------------------------------------------------------------
      // Object
      object = getObjectExt(result["object"])
      if (TypeOf(object) = "null") {
        error (DynamicTemplate("DevModeErrorCantFindObject", result["object"]))
      }
      // Attribute
      attribute = result["attribute"]
      current_value = GetAttribute(object, attribute)
      if (TypeOf(current_value) = "null" and result["istoken"] <> "=") {
        error (DynamicTemplate("DevModeErrorCantFindAttribute", result["attribute"]))
      }
      // Value
      value = result["value"]
      // ----------------------------------------------------------------------------------------------------
      // SET VALUE
      // If an actual equals sign has been set, the input is treated as an assignment.
      // ----------------------------------------------------------------------------------------------------
      if (result["istoken"] = "=") {
        // ----------------------------------------------------------------------------------------------------
        // BOOLEAN-TOKENS
        // Short notation for Boolean states
        // ----------------------------------------------------------------------------------------------------
        if (result["value"] = "?") {
          value = true
        }
        else if (result["value"] = "!") {
          value = false
        }
        else if (result["value"] = "~") {
          value = not GetBoolean (object, attribute)
        }
        else if (result["valkeytoken"] = "[") {
          value = NewList ()
          if (result["value"] <> "") {
            list = Split(result["value"], ",")
            foreach (item, list) {
              list add (value, Eval(Trim(item)))
            }
          }
        }
        else if (result["valkeytoken"] = "{") {
            value = NewDictionary ()
            if (result["value"] <> "") {
              list = Split(result["value"], ",")
              foreach (assign, list) {
                if (not Instr(assign, ":") = 0) {
                  dic = Split(assign, ":")
                  dickey = dic[0]
                  dicvalue = dic[1]
                  dictionary add (value, dickey, Eval(Trim(dicvalue)))
                }
                else {
                  error (Template("DevModeErrorWrongFormat"))
                }
              }
            }
          }
          else if (result["valobject"] <> "") {
            valobject = getObjectExt(result["valobject"])
            if (TypeOf(valobject) = "null") {
              error (DynamicTemplate("DevModeErrorCantFindObject", result["valobject"]))
            }
            // Valattribute
            if (result["valattribute"] <> "") {
              valattribute = result["valattribute"]
              value = GetAttribute(valobject, valattribute)
              if (TypeOf(value) = "null") {
                error (DynamicTemplate("DevModeErrorCantFindAttribute", result["valattribute"]))
              }
            }
          }
          else {
            value = Eval(result["value"])
          }
          // ----------------------------------------------------------------------------------------------------
          // VALUE-LIST
          // Creating a new list
          // ----------------------------------------------------------------------------------------------------
          // ----------------------------------------------------------------------------------------------------
          // VALUE-DICTIONARY
          // Creating a new dictionary
          // ----------------------------------------------------------------------------------------------------
          // ----------------------------------------------------------------------------------------------------
          // VALUE-OBJECT AND VALUE-ATTRIBUTE
          // Assigning an attribute from another object
          // ----------------------------------------------------------------------------------------------------
          // ----------------------------------------------------------------------------------------------------
          // VALUE EVALUATION
          // Value is evaluated
          // ----------------------------------------------------------------------------------------------------
          // ----------------------------------------------------------------------------------------------------
          // SET-ATTRIBUTE-LIST
          // Add a new item to a list or overwrite an existing one
          // ----------------------------------------------------------------------------------------------------
          if (result["keytoken"] = "[") {
            if (TypeOf(current_value) <> "list" and TypeOf(current_value) <> "objectlist" and TypeOf(current_value) <> "stringlist") {
              current_value = NewList ()
            }
            if (result["key"] <> "") {
              if (not IsNumeric(result["key"])) {
                error (Template("DevModeErrorWrongTyp"))
              }
              else if (ToInt(result["key"]) < ListCount(current_value)) {
                list remove (current_value, ListItem(current_value, ToInt(result["key"])))
              }
            }
            list add (current_value, value)
            value = NewList ()
            value = current_value
          }
          else if (result["keytoken"] = "{") {
              if (TypeOf(current_value) <> "dictionary" and TypeOf(current_value) <> "objectdictionary" and TypeOf(current_value) <> "stringdictionary") {
                current_value = NewDictionary ()
              }
              if (result["key"] <> "") {
                if (result["key"] in current_value) {
                  dictionary remove (current_value, result["key"])
                }
                dictionary add (current_value, result["key"], value)
                value = NewDictionary ()
                value = current_value
              }
            }
            // ----------------------------------------------------------------------------------------------------
            // SET-ATTRIBUTE-DICTIONARY
            // Add a new key to a dictionary or overwrite an existing one
            // ----------------------------------------------------------------------------------------------------
            // ----------------------------------------------------------------------------------------------------
            // VALUE-ASSIGNMENT
            // The value is assigned to the attribute and a corresponding output appears
            // ----------------------------------------------------------------------------------------------------
            set (object, attribute, value)
            DevModeOutput (Template("DevModeComSetAttribute") + object.name + "." + attribute + "=" + ParseToFlyScript(value))
          }
          else {
            key = ""
            // ----------------------------------------------------------------------------------------------------
            // GET-ATTRIBUTE-LIST
            // If the attribute is a list and the specified key is in it, the content is read out.
            // ----------------------------------------------------------------------------------------------------
            if (result["keytoken"] = "[") {
              if (TypeOf(current_value) <> "list" and TypeOf(current_value) <> "objectlist" and TypeOf(current_value) <> "stringlist") {
                error (Template("DevModeErrorWrongTyp"))
              }
              else if (not IsNumeric(result["key"])) {
                error (Template("DevModeErrorWrongTyp"))
              }
              else if (ToInt(result["key"]) > ListCount(current_value)-1) {
                error (Template("DevModeErrorWrongKey"))
              }
              else {
                current_value = ListItem(current_value, ToInt(result["key"]))
              }
              key = "[" + result["key"] + "]"
            }
            // ----------------------------------------------------------------------------------------------------
            // GET-ATTRIBUTE-DICTIONARY
            // If the attribute is a dictionary and the specified key is in it, the content is read out.
            // ----------------------------------------------------------------------------------------------------
            if (result["keytoken"] = "{") {
                if (TypeOf(current_value) <> "dictionary" and TypeOf(current_value) <> "objectdictionary" and TypeOf(current_value) <> "stringdictionary") {
                  error (Template("DevModeErrorWrongTyp"))
                }
                else if (not result["key"] in current_value) {
                  error (Template("DevModeErrorWrongKey"))
                }
                else {
                  current_value = DictionaryItem(current_value, result["key"])
                }
                key = "{" + result["key"] + "}"
              }
              // ----------------------------------------------------------------------------------------------------
              // VALUE-READING
              // The value of the attribute is read out
              // ----------------------------------------------------------------------------------------------------
              DevModeOutput (Template("DevModeComGetAttribute") + object.name + "." + attribute + key + "=" + ParseToFlyScript(current_value))
            }
            // ----------------------------------------------------------------------------------------------------
            // GET VALUE
            // If no equal sign has been set, the result is treated as readout.
            // ----------------------------------------------------------------------------------------------------
          }
          else {
            error (Template("DevModeErrorWrongFormat"))
          }
          // ----------------------------------------------------------------------------------------------------
          // FAIL MATCH
          // An error message is displayed if the user's entry is incorrect.
          // ----------------------------------------------------------------------------------------------------
  ]]></function>
  <function name="ParseToFlyScript" parameters="text" type="string"><![CDATA[
    switch (TypeOf(text)) {
      // ----------------------------------------------------------------------------------------------------
      // STRING
      // ----------------------------------------------------------------------------------------------------
      case ("string") {
        parsetext = "\"" + text + "\""
      }
      // ----------------------------------------------------------------------------------------------------
      // OBJECT
      // ----------------------------------------------------------------------------------------------------
      case ("object") {
        parsetext = text.name
      }
      // ----------------------------------------------------------------------------------------------------
      // SCRIPT
      // ----------------------------------------------------------------------------------------------------
      case ("script") {
        parsetext = "<" + Replace(ToString(text), "Script: ", "") + ">"
      }
      // ----------------------------------------------------------------------------------------------------
      // LIST
      // ----------------------------------------------------------------------------------------------------
      case ("list", "stringlist", "objectlist") {
        list = NewStringList()
        foreach (item, text) {
          switch (TypeOf(item)) {
            case ("string") item = "\"" + item + "\""
            case ("object") item = item.name
            default item = ToString(item)
          }
          list add (list, item)
        }
        parsetext = "[" + Join (list, ",") + "]"
      }
      // ----------------------------------------------------------------------------------------------------
      // DICTIONARY
      // ----------------------------------------------------------------------------------------------------
      case ("dictionary", "stringdictionary", "objectdictionary", "scriptdictionary") {
        list = NewStringList()
        foreach (key, text) {
          item = DictionaryItem(text, key)
          switch (TypeOf(item)) {
            case ("string") item = "\"" + item + "\""
            case ("object") item = item.name
            case ("script") item = "<" + Replace(ToString(item), "Script: ", "") + ">"
            default item = ToString(item)
          }
          list add (list, key + ":" + item)
        }
        parsetext = "{" + Join (list, ",") + "}"
      }
      // ----------------------------------------------------------------------------------------------------
      // OTHER TYPES
      // ----------------------------------------------------------------------------------------------------
      default {
        parsetext = ToString(text)
      }
    }
    return (parsetext)
  ]]></function>
  <function name="DevModeOutput" parameters="str"><![CDATA[
    if (game.devmode_showinfos) {
      if (game.devmode_ownfontcolour) {
        col = " color=\"" + game.devmode_fontcolour + "\""
      }
      else {
        col = ""
      }
      msg ("<font" + col + ">" + str + "</font>")
    }
  ]]></function>
  <function name="DevModeOutputError" parameters="str"><![CDATA[
    if (game.devmode_showinfos) {
      msg ("<font color=\"red\">" + str + "</font>")
    }
  ]]></function>
  <function name="setWithoutChange" parameters="obj, att, val"><![CDATA[
    cha = "changed" + att
    bla => {
    }
    scr => {
    }
    if (obj = null) {
      error (Template("DevModeErrorObjectNotRecognised"))
    }
    if (HasAttribute (obj, cha)) {
      scr = GetAttribute (obj, cha)
      set (obj, cha, bla)
      set (obj, att, val)
      set (obj, cha, scr)
    }
    else {
      set (obj, att, val)
    }
  ]]></function>
  <function name="setDevMode">
    if (HasAttribute(game, "devmode_active")) {
      if (game.devmode_active) {
        DevModeOutput (Template("DevModeActive"))
        if (HasAttribute(game, "devmode_attributes") and not DictionaryCount(game.devmode_attributes) = 0) {
          foreach (key, game.devmode_attributes) {
            command = key + "=" + ToString(DictionaryItem(game.devmode_attributes, key))
            commandOutput ("#" + command)
            ParseToQuestCode (command)
          }
        }
        if (game.devmode_changepov) {
          commandOutput ("#to " + game.devmode_pov)
          HandleSingleCommand ("#to " + game.devmode_pov)
        }
        if (game.devmode_changepovpos) {
          commandOutput ("#go " + game.devmode_povpos)
          HandleSingleCommand ("#go " + game.devmode_povpos)
        }
        if (game.devmode_setverbs) {
          setVerbs
        }
        if (game.devmode_setinitscript and HasScript(game, "devmode_initscript")) {
          msg ("")
          DevModeOutput (Template("DevModeStartScript"))
          do (game, "devmode_initscript")
        }
        msg ("")
      }
    }
  </function>
  <function name="getTableDataNames" parameters="empty">
    data = NewStringList ()
    list add (data, "{\"name\":\"game\"}")
    foreach (obj, AllObjects()) {
      list add (data, "{\"name\":\"" + obj.name + "\"}")
    }
    datastr = "[" + Join (data, ",") + "]"
    JS.setTableData ("names", datastr)
  </function>
  <function name="getTableDataAttr" parameters="name">
    data = NewStringList ()
    obj = GetObject (name)
    foreach (attr, GetAttributeNames (obj, true)) {
      val = ParseToFlyScript (GetAttribute (obj, attr))
      list add (data, "{\"attribute\":\"" + attr + "\",\"value\":\"" + Replace(val, "\"", "\\\"") + "\"}")
    }
    datastr = "[" + Join (data, ",") + "]"
    JS.setTableData ("attr", datastr)
  </function>
  <function name="setTableData" parameters="command">
    commandOutput ("#" + command)
    ParseToQuestCode (command)
  </function>
  <function name="commandOutput" parameters="command"><![CDATA[
    msg ("")
    DevModeOutput ("> " + command)
  ]]></function>
  <function name="setVerbs">
    verbs = game.devmode_verbs
    foreach (object, AllObjects()) {
      if (HasAttribute(object, "displayverbs")) {
        object.displayverbs = ListCombine (object.displayverbs, verbs)
      }
      if (HasAttribute(object, "inventoryverbs")) {
        object.inventoryverbs = ListCombine (object.inventoryverbs, verbs)
      }
    }
    game.enablehyperlinks = true
    msg ("")
    DevModeOutput (Template("DevModeSetVerbs"))
  </function>
  <function name="getObjectExt" parameters="name" type="object">
    obj = GetObject(name)
    if (obj = null) {
      foreach (sobj, AllObjects()) {
        if (HasAttribute(sobj, "alias")) {
          if (LCase(sobj.alias) = LCase(name)) {
            return (sobj)
          }
        }
      }
    }
    return (obj)
  </function>
  <function name="selfTest"><![CDATA[
    msg ("")
    DevModeOutput ("<b>Start DevMode-Selftest...</b>")
    // ----------------------------------------------------------------------------------------------------
    // TESTOBJECTS
    // Generate testobjects
    // ----------------------------------------------------------------------------------------------------
    create ("testobject1")
    create ("testobject2")
    testobject1.testattribut = ""
    // ----------------------------------------------------------------------------------------------------
    // COMMANDS
    // Generate commmands for testing
    // ----------------------------------------------------------------------------------------------------
    commands = NewDictionary ()
    // ----------------------------------------------------------------------------------------------------
    // OBJECT-COMMANDS
    // Unlike the commands in the game, they are executed directly and without detours via intercept scripts
    // ----------------------------------------------------------------------------------------------------
    dictionary add (commands, "#take testobject1", "Got (testobject1)")
    dictionary add (commands, "#drop testobject1", "Contains (game.pov.parent, testobject1)")
    dictionary add (commands, "#put testobject1 in testobject2", "Contains (testobject2, testobject1)")
    dictionary add (commands, "#open testobject1", "testobject1.isopen")
    dictionary add (commands, "#close testobject1", "not testobject1.isopen")
    dictionary add (commands, "#on testobject1", "IsSwitchedOn(testobject1)")
    dictionary add (commands, "#off testobject1", "not IsSwitchedOn(testobject1)")
    dictionary add (commands, "#to testobject1", "game.pov = testobject1")
    dictionary add (commands, "#go testobject2", "game.pov.parent = testobject2")
    // ----------------------------------------------------------------------------------------------------
    // OBJECT-ATTRIBUTES
    // assign and read attributes
    // ----------------------------------------------------------------------------------------------------
    // BOOLEAN
    dictionary add (commands, "#testobject1.testattribut=true", "TypeOf(testobject1.testattribut) = \"boolean\" and testobject1.testattribut=true")
    dictionary add (commands, "#testobject1.testattribut=false", "TypeOf(testobject1.testattribut) = \"boolean\" and testobject1.testattribut=false")
    dictionary add (commands, "#testobject1.testattribut=?", "TypeOf(testobject1.testattribut) = \"boolean\" and testobject1.testattribut=true")
    dictionary add (commands, "#testobject1.testattribut=!", "TypeOf(testobject1.testattribut) = \"boolean\" and testobject1.testattribut=false")
    dictionary add (commands, "#testobject1.testattribut=~", "TypeOf(testobject1.testattribut) = \"boolean\" and testobject1.testattribut=true")
    // STRING
    dictionary add (commands, "#testobject1.testattribut=\"teststring\"", "TypeOf(testobject1.testattribut) = \"string\" and testobject1.testattribut=\"teststring\"")
    // INTEGER
    dictionary add (commands, "#testobject1.testattribut=25", "TypeOf(testobject1.testattribut) = \"int\" and testobject1.testattribut = 25")
    // DOUBLE
    dictionary add (commands, "#testobject1.testattribut=25.25", "TypeOf(testobject1.testattribut) = \"double\" and testobject1.testattribut = 25.25")
    // OBJECT
    dictionary add (commands, "#testobject1.testattribut=testobject1", "TypeOf(testobject1.testattribut) = \"object\" and testobject1.testattribut = testobject1")
    // LIST
    dictionary add (commands, "#testobject1.testattribut=[]", "TypeOf(testobject1.testattribut) = \"list\" and ListCount(testobject1.testattribut) = 0")
    dictionary add (commands, "#testobject1.testattribut=[\"testitem1\",\"testitem2\",testobject1,testobject2]", "TypeOf(testobject1.testattribut) = \"list\" and ListCount(testobject1.testattribut) = 4 and TypeOf(ListItem(testobject1.testattribut, 0)) = \"string\" and ListItem(testobject1.testattribut, 0) = \"testitem1\" and TypeOf(ListItem(testobject1.testattribut, 1)) = \"string\" and ListItem(testobject1.testattribut, 1) = \"testitem2\" and TypeOf(ListItem(testobject1.testattribut, 2)) = \"object\" and ListItem(testobject1.testattribut, 2) = testobject1 and TypeOf(ListItem(testobject1.testattribut, 3)) = \"object\" and ListItem(testobject1.testattribut, 3) = testobject2")
    dictionary add (commands, "#testobject1.testattribut[2]=\"newtestitem2\"", "TypeOf(testobject1.testattribut) = \"list\" and ListCount(testobject1.testattribut) = 4 and TypeOf(ListItem(testobject1.testattribut, 3)) = \"string\" and ListItem(testobject1.testattribut, 3) = \"newtestitem2\"")
    dictionary add (commands, "#testobject1.testattribut[]=\"newtestitem5\"", "TypeOf(testobject1.testattribut) = \"list\" and ListCount(testobject1.testattribut) = 5 and ListItem(testobject1.testattribut, 4) = \"newtestitem5\"")
    dictionary add (commands, "#testobject1.testattribut[1]", "")
    // DICTIONARY
    dictionary add (commands, "#testobject1.testattribut={}", "TypeOf(testobject1.testattribut) = \"dictionary\" and DictionaryCount(testobject1.testattribut) = 0")
    dictionary add (commands, "#testobject1.testattribut={testkey1:\"testitem1\",testkey2:\"testitem2\",testkey3:testobject1,testkey4:testobject2}", "TypeOf(testobject1.testattribut) = \"dictionary\" and DictionaryCount(testobject1.testattribut) = 4 and TypeOf(DictionaryItem(testobject1.testattribut, \"testkey1\")) = \"string\" and DictionaryItem(testobject1.testattribut, \"testkey1\") = \"testitem1\" and TypeOf(DictionaryItem(testobject1.testattribut, \"testkey2\")) = \"string\" and DictionaryItem(testobject1.testattribut, \"testkey2\") = \"testitem2\" and TypeOf(DictionaryItem(testobject1.testattribut, \"testkey3\")) = \"object\" and DictionaryItem(testobject1.testattribut, \"testkey3\") = testobject1 and TypeOf(DictionaryItem(testobject1.testattribut, \"testkey4\")) = \"object\" and DictionaryItem(testobject1.testattribut, \"testkey4\") = testobject2")
    dictionary add (commands, "#testobject1.testattribut{testkey4}=\"newtestitem4\"", "TypeOf(testobject1.testattribut) = \"dictionary\" and DictionaryCount(testobject1.testattribut) = 4 and TypeOf(DictionaryItem(testobject1.testattribut, \"testkey4\")) = \"string\" and DictionaryItem(testobject1.testattribut, \"testkey4\") = \"newtestitem4\"")
    dictionary add (commands, "#testobject1.testattribut{testkey1}", "")
    // OBJECTATTRIBUT
    dictionary add (commands, "#testobject1.testattribut=testobject2.name", "TypeOf(testobject1.testattribut) = \"string\" and testobject1.testattribut=\"testobject2\"")
    // ALL TYPES
    dictionary add (commands, "#testobject1.testattribut", "")
    // ----------------------------------------------------------------------------------------------------
    // TESTING
    // Testing the Commands
    // ----------------------------------------------------------------------------------------------------
    iserror = false
    foreach (command, commands) {
      if (not iserror) {
        on ready {
          DevModeOutput ("<br/>&gt; " + command)
          HandleSingleCommand (command)
          on ready {
            compare = ToString(DictionaryItem(commands, command))
            if (compare <> "") {
              result = Eval(compare)
            }
            DevModeOutput ("Quest-Presentation: testobject1.testattribut = " + ToString(testobject1.testattribut))
            if (not result) {
              iserror = true
              DevModeOutputError (Template("DevModeComSelfTestFailed"))
              Log (ToString(ListItem(testobject1.testattribut, 2)))
            }
          }
        }
      }
    }
  ]]></function>
  <function name="InitInterface"><![CDATA[
    // Added by KV for transcript
    // Use JSSafe to remove any offensive characters!  - KV   May 27, 2018
    jsgamename = JSSafe(game.gamename)
    JS.eval ("var gameName = '"+jsgamename+"';var transcriptName = gameName;")
    if (GetBoolean(game,"savetranscript")) {
      JS.eval ("var savingTranscript = true;")
      JS.replaceTranscriptString (game.transcriptstring)
    }
    // End of addition by KV for transcript
    if (game.setcustomwidth) {
      JS.setGameWidth (game.customwidth)
    }
    if (game.setcustompadding) {
      JS.setGamePadding (game.custompaddingtop, game.custompaddingbottom, game.custompaddingleft, game.custompaddingright)
    }
    if (game.externalstylesheets <> null) {
      foreach (stylesheet, game.externalstylesheets) {
        JS.addExternalStylesheet (stylesheet)
      }
    }
    if (game.setbackgroundopacity) {
      SetBackgroundOpacity (game.backgroundopacity)
    }
    SetBackgroundColour (game.defaultbackground)
    SetForegroundColour (game.defaultforeground)
    SetLinkForegroundColour (game.defaultlinkforeground)
    if (LengthOf(game.backgroundimage) > 0) {
      SetBackgroundImage (game.backgroundimage)
    }
    JS.setCompassDirections (Join(game.compassdirections, ";"))
    JS.setInterfaceString ("InventoryLabel", "Inventory")
    JS.setInterfaceString ("StatusLabel", "Status")
    JS.setInterfaceString ("PlacesObjectsLabel", "Places and Objects")
    JS.setInterfaceString ("CompassLabel", "Compass")
    JS.setInterfaceString ("InButtonLabel", "in")
    JS.setInterfaceString ("OutButtonLabel", "out")
    JS.setInterfaceString ("EmptyListLabel", "(empty)")
    JS.setInterfaceString ("NothingSelectedLabel", "(nothing selected)")
    JS.setInterfaceString ("TypeHereLabel", "Type here...")
    JS.setInterfaceString ("ContinueLabel", "Continue...")
    JS.SetMenuBackground (game.menubackground)
    JS.SetMenuForeground (game.menuforeground)
    JS.SetMenuHoverBackground (game.menuhoverbackground)
    JS.SetMenuHoverForeground (game.menuhoverforeground)
    JS.SetMenuFontName (game.menufont)
    JS.SetMenuFontSize (game.menufontsize + "pt")
    if (not game.underlinehyperlinks) {
      JS.TurnOffHyperlinksUnderline ()
    }
    ResetCommandBarFormat
    if (game.showcommandbar) {
      JS.uiShow ("#txtCommandDiv")
    }
    else {
      JS.uiHide ("#txtCommandDiv")
    }
    if (HasString(game, "panelcontents")) {
      SetFramePicture (game.panelcontents)
    }
    if (game.gridmap) {
      JS.ShowGrid (game.mapsize)
      Grid_SetScale (game.mapscale)
      if (game.pov <> null) {
        if (game.pov.parent <> null) {
          Grid_Redraw
          Grid_DrawPlayerInRoom (game.pov.parent)
        }
      }
    }
    // Added by the Pixie
    // Note that panesVisible in playercore.js must be updated too
    // This line will get the save confirmation to appear in the right font and colour
    JS.setCss ("body", "color:" + game.defaultforeground + ";font-family:" + game.defaultfont + ";font-size:" + game.defaultfontsize + "pt;")
    // various new options
    if (HasString(game, "bordercolour")) {
      JS.setCss ("#gameBorder", "border-left:1px solid " + game.bordercolour + ";border-right:1px solid " + game.bordercolour)
    }
    if (not game.classiclocation) {
      JS.setCss ("#status", "background-image:none")
      if (HasString(game, "customlocationcolour")) {
        JS.setCss ("#status", "background-color:" + game.customlocationcolour)
      }
      else {
        JS.setCss ("#status", "background:transparent")
      }
      if (HasString(game, "customlocationtextcolour")) {
        JS.setCss ("#status", "color:" + game.customlocationtextcolour)
      }
      if (HasString(game, "customlocationbordercolour")) {
        JS.setCss ("#status", "border:1px solid " + game.customlocationbordercolour)
      }
      else {
        JS.setCss ("#status", "border:none")
      }
      if (HasString(game, "locationbarimage")) {
        if (not Trim(game.locationbarimage) = "") {
          url = GetFileURL(game.locationbarimage)
          JS.eval ("$('.ui-widget-header').css('background-image','url(" + url + ")');")
        }
      }
    }
    // request (Show, "Location")
    if (game.showlocation) {
      JS.uiShow ("#location")
      JS.setCss ("#status", "display:block")
    }
    else {
      JS.setCss ("#status", "display:none")
    }
    if (HasString(game, "marginscolour")) {
      JS.setCss ("body", "background-color:" + game.marginscolour)
    }
    if (game.turnoffsavebutton) {
      JS.setCss ("#controlButtons", "display:none")
    }
    if (game.turnoffcompass) {
      JS.setCss ("#compassLabel", "display:none;")
      JS.setCss ("#compassAccordion", "display:none;")
    }
    if (game.turnoffinventory) {
      JS.setCss ("#inventoryLabel", "display:none")
      JS.setCss ("#inventoryAccordion", "display:none")
    }
    if (game.turnoffplacesandobjects) {
      JS.setCss ("#placesObjectsLabel", "display:none")
      JS.setCss ("#placesObjectsAccordion", "display:none")
    }
    if (game.statusandcompassattop) {
      JS.eval ("$('#commandPane').insertBefore('#inventoryLabel')")
      JS.eval ("$('#customStatusPane').insertBefore('#inventoryLabel')")
      JS.eval ("$('#statusVarsLabel').insertBefore('#inventoryLabel')")
      JS.eval ("$('#statusVarsAccordion').insertBefore('#inventoryLabel')")
      JS.eval ("$('#compassLabel').insertBefore('#inventoryLabel')")
      JS.eval ("$('#compassAccordion').insertBefore('#inventoryLabel')")
    }
    if (game.showpanes and game.commandpane) {
      JS.setCss ("#commandPane", "display:block")
    }
    if (game.showpanes and game.customstatuspane) {
      JS.setCss ("#customStatusPane", "display:block")
    }
    if (game.colourblend) {
      JS.colourBlend (game.colourblendtop, game.colourblendbottom)
    }
    if (game.borderlesscursor) {
      JS.addScript ("<style>#txtCommand { outline:none; border:none; margin:0; padding:0; width:100px; background-color:transparent;}</style>")
      JS.setCss ("#txtCommandDiv", "color:" + game.defaultforeground)
      JS.eval ("$('#txtCommandPrompt').html('" + game.commandcursor + "')")
    }
    else if (game.shadowbox) {
      JS.addScript ("<style>#txtCommand { outline:none; border:none; margin:2px; padding:7px; width:100 px;box-shadow: 0px 0px 15px 5px #888;}</style>")
    }
    if (game.panestheme = "Midnight") {
      JS.setPanes ("white", "midnightblue", "midnightblue", "skyblue")
    }
    if (game.panestheme = "Nature") {
      JS.setPanes ("#A1C935", "#254117", "#306754", "#A1C935", "green")
    }
    if (game.panestheme = "Parchment") {
      JS.setPanes ("#493D26", "#FAEBD7", "#FAEBD7", "#493D26", "#C88141")
    }
    if (game.panestheme = "Vanilla") {
      JS.setPanes ("black", "white")
    }
    if (game.panestheme = "Black") {
      JS.setPanes ("orange", "black", "black", "orange")
    }
    if (game.panestheme = "Blood") {
      JS.setPanes ("orange", "#800000", "#800000", "orange", "yellow")
    }
    if (game.panestheme = "Tranquil") {
      JS.setPanes ("midnightblue", "skyblue", "white", "midnightblue", "blue")
    }
    if (game.respondtogridclicks) {
      JS.respondToGridClicks (true)
    }
    //
    // -----------------------------------------------------------------------
    // This is in the original, but must come last
    if (not game.showborder) {
      JS.hideBorder ()
    }
    if (game.showpanes) {
      JS.panesVisible (true)
    }
    else {
      JS.panesVisible (false)
    }
    JS.getDivCount ()
    if (not game.pov = null) {
      JS.updateLocation (CapFirst(GetDisplayName(game.pov.parent)))
    }
    if (game.feature_devmode) {
      setDevMode
    }
    InitUserInterface
    if (HasScript(game, "inituserinterface")) {
      do (game, "inituserinterface")
    }
  ]]></function>
  <function name="InitUserInterface">
  </function>
  <function name="StartGame"><![CDATA[
    StartTurnOutputSection
    if (game.showtitle) {
      JS.StartOutputSection ("title")
      PrintCentered ("<span style=\"font-size:260%\">" + game.gamename + "</span>")
      if (game.subtitle <> null) {
        if (LengthOf(game.subtitle) > 0) {
          PrintCentered ("<span style=\"font-size:130%\">" + game.subtitle + "</span>")
        }
      }
      if (game.author <> null) {
        if (LengthOf(game.author) > 0) {
          PrintCentered ("<br/><span style=\"font-size:140%\">by " + game.author + "</span>")
        }
      }
      msg ("<div style=\"margin-top:20px\"></div>")
      JS.EndOutputSection ("title")
    }
    if (game.pov = null) {
      playerObject = GetObject("player")
      if (playerObject = null) {
        if (ListCount(AllObjects()) > 0) {
          firstRoom = ObjectListItem(AllObjects(), 0)
        }
        else {
          create ("room")
          firstRoom = room
        }
        create ("player")
        player.parent = firstRoom
      }
      game.pov = player
    }
    else {
      InitPOV (null, game.pov)
    }
    InitStatusAttributes
    UpdateStatusAttributes
    InitVerbsList
    if (HasScript(game, "start")) {
      do (game, "start")
    }
    foreach (obj, AllObjects()) {
      if (HasScript(obj, "_initialise_")) {
        do (obj, "_initialise_")
      }
    }
    UpdateStatusAttributes
    UpdateObjectLinks
    on ready {
      if (game.gridmap) {
        Grid_DrawPlayerInRoom (game.pov.parent)
      }
      if (game.displayroomdescriptiononstart) {
        OnEnterRoom (null)
      }
      UpdateStatusAttributes
      UpdateObjectLinks
    }
    // Added by KV to use the old JS clearScreen if the transcript is disabled
    if (GetBoolean(game, "notranscript")) {
      JS.eval ("transcriptEnabled = false;")
    }
    game.runturnscripts = false
    FinishTurn
  ]]></function>
  <function name="InitVerbsList">
    game.verbattributes = NewStringList()
    game.verbattributeslookup = NewObjectDictionary()
    foreach (cmd, AllCommands()) {
      if (HasString(cmd, "property")) {
        list add (game.verbattributes, cmd.property)
        dictionary add (game.verbattributeslookup, cmd.property, cmd)
      }
    }
  </function>
  <function name="GetDisplayVerbs" parameters="object" type="stringlist">
    if (Contains(game.pov, object)) {
      baselist = object.inventoryverbs
    }
    else {
      baselist = object.displayverbs
    }
    if (not game.autodisplayverbs or GetBoolean(object, "usestandardverblist") or not HasAttribute(game, "verbattributes")) {
      return (baselist)
    }
    else {
      if (HasAttribute(object, "generatedverbslist")) {
        verbs = object.generatedverbslist
      }
      else {
        verbs = NewStringList()
        foreach (attr, GetAttributeNames(object, false)) {
          if (ListContains(game.verbattributes, attr)) {
            cmd = ObjectDictionaryItem(game.verbattributeslookup, attr)
            if (HasString(cmd, "displayverb")) {
              displayverb = CapFirst(cmd.displayverb)
            }
            else {
              displayverb = CapFirst(attr)
            }
            if (not ListContains(baselist, displayverb)) {
              list add (verbs, displayverb)
            }
          }
        }
        object.generatedverbslist = verbs
      }
      if (GetBoolean(object, "useindividualverblist")) {
        return (verbs)
      }
      else {
        return (ListCombine(baselist, verbs))
      }
    }
  </function>
  <function name="InitPOV" parameters="oldPOV, newPOV"><![CDATA[
    if (oldPOV <> null) {
      oldPOV.alias = oldPOV.external_alias
      oldPOV.alt = oldPOV.external_alt
      oldPOV.look = oldPOV.external_look
      oldPOV.gender = oldPOV.external_gender
      oldPOV.article = oldPOV.external_article
      oldPOV.possessive = oldPOV.external_possessive
    }
    newPOV.external_alias = newPOV.alias
    newPOV.external_alt = newPOV.alt
    newPOV.external_look = newPOV.look
    newPOV.external_gender = newPOV.gender
    newPOV.external_article = newPOV.article
    newPOV.external_possessive = newPOV.possessive
    if (not GetBoolean(newPOV, "pov_used")) {
      if (newPOV.alt = null) {
        newPOV.pov_alt = newPOV.pov_alt
      }
      else {
        newPOV.pov_alt = ListCombine(newPOV.alt, newPOV.pov_alt)
      }
      if (newPOV.alias <> null) {
        list add (newPOV.pov_alt, newPOV.alias)
      }
      if (game.showmoney and not HasInt(newPOV, "money")) {
        newPOV.money = 0
      }
      if (game.showhealth) {
        newPOV.health = 100
        newPOV.changedhealth => {
          if (this.health > 100) {
            this.health = 100
          }
          else if (this.health = 0) {
            if (HasScript(game, "onhealthzero")) {
              do (game, "onhealthzero")
            }
          }
          else if (this.health < 0) {
            this.health = 0
            // changedhealth will be called again so the onhealthzero script will run
          }
        }
      }
      newPOV.pov_used = true
    }
    newPOV.alias = newPOV.pov_alias
    newPOV.alt = newPOV.pov_alt
    newPOV.look = newPOV.pov_look
    newPOV.gender = newPOV.pov_gender
    newPOV.article = newPOV.pov_article
    newPOV.possessive = newPOV.pov_possessive
  ]]></function>
  <function name="FinishTurn">
    if (GetBoolean(game,"runturnscripts")) {
      if (not GetBoolean(game, "suppressturnscripts")) {
        RunTurnScripts
      }
    }
    game.runturnscripts = false
    game.suppressturnscripts = false
    UpdateStatusAttributes
    CheckDarkness
    UpdateObjectLinks
  </function>
  <function name="WhereAmI" parameters="s">
    game.questplatform = s
  </function>
  <function name="HandleSingleCommand" parameters="command"><![CDATA[
    if (game.ott_test) {
      get input {
        list add (game.typing_test, command)
      }
    }
    else {
      if (LCase(command) = LCase(Template("Again1")) or LCase(command) = LCase(Template("Again2"))) {
        // First handle AGAIN
        if (not game.pov.currentcommand = null) {
          HandleSingleCommand (game.pov.currentcommand)
        }
        else {
          msg ("There is nothing to repeat.")
        }
      }
      else {
        // Check through all commands for any that match
        candidates = NewObjectList()
        foreach (cmd, ScopeCommands()) {
          if (IsRegexMatch(cmd.pattern, command, cmd.name)) {
            list add (candidates, cmd)
          }
        }
        maxstrength = -1
        thiscommand = null
        // Pick the best match
        foreach (candidate, candidates) {
          strength = GetMatchStrength(candidate.pattern, command, candidate.name)
          // favour commands defined later, so an author can override a library command...
          if (strength >= maxstrength) {
            // ... except if the command defined later (candidate) has no parent, and the current best
            // match (thiscommand) does have a parent. We want to favour any commands defined in rooms
            // over global candidates.
            skip = false
            if (thiscommand <> null) {
              if (thiscommand.parent <> null and candidate.parent = null) {
                skip = true
              }
            }
            if (not skip) {
              thiscommand = candidate
              maxstrength = strength
            }
          }
        }
        if (thiscommand = null) {
          if (HasScript(game, "unresolvedcommandhandler")) {
            params = NewDictionary()
            dictionary add (params, "command", command)
            do (game, "unresolvedcommandhandler", params)
          }
          else {
            msg (Template("UnrecognisedCommand"))
          }
          HandleNextCommandQueueItem
        }
        else {
          varlist = Populate(thiscommand.pattern, command, thiscommand.name)
          HandleSingleCommandPattern (command, thiscommand, varlist)
        }
      }
    }
  ]]></function>
  <function name="BoundaryLock">
    if (game.boundary_lock) {
      JS.uiHide ("#txtCommandDiv")
    }
    else {
      msg (" ")
    }
  </function>
  <function name="BoundaryUnlock">
    if (game.boundary_lock = false) {
      JS.uiShow ("#txtCommandDiv")
    }
    else {
      msg (" ")
    }
  </function>
  <function name="goodguestslisten"><![CDATA[
    // THIS FUNCTION USES TEXT LIST
    // Check if the global list actually exists and has items
    if (ListCount(game.active_text_list) > 0) {
      // Pull the first item
      current_line = ListItem(game.active_text_list, 0)
      // Print it
      msg (current_line)
      // Remove it so the next loop gets the next line
      list remove (game.active_text_list, current_line)
      // Set the timer using the global delay
      SetTimeout (game.active_delay_time) {
      }
    }
    else {
      if (HasScript(game, "after_dialogue_script")) {
        do (game, "after_dialogue_script")
      }
    }
  ]]></function>
  <function name="anykey"><![CDATA[
    Boundary_Lock = true
    BoundaryLock
    if (game.active_play_text = null) {
      game.active_play_text = NewStringList()
    }
    if (ListCount(game.active_play_text) > 0) {
      current_line = ListItem(game.active_play_text, 0)
      if (IsRegexMatch ("<br/>", current_line)) {
        parts = Split(current_line, "<br/>")
        foreach (p, parts) {
          TextFX_Typewriter (p, 20)
        }
      }
      else {
        TextFX_Typewriter (current_line, 20)
      }
      list remove (game.active_play_text, current_line)
      // Set a wait
      JS.eval ("$('#endWaitDiv').hide();")
      JS.eval ("$('#divOutput').append('<span id=\"temp-cursor\"> >> </span>');")
      wait {
        JS.eval ("$('#temp-cursor').remove();")
        anykey
      }
    }
    else {
      if (HasScript(game, "after_dialogue_script")) {
        game.nowhere_intro = null
        game.nowhere_intro = NewStringList ()
        game.active_play_text = null
        game.active_play_text = NewStringList ()
        do (game, "after_dialogue_script")
      }
    }
  ]]></function>
  <function name="typingtest"><![CDATA[
    if (game.ott_test) {
      SetTimeout (10) {
        game.ott_test = false
        typingtest
      }
    }
    else {
      count = 0
      foreach (item, game.typing_test) {
        if (item = "test") {
          count = count + 1
        }
        else {
          count = count  + 0
        }
      }
      on ready {
        if (count < 3) {
          msg ("You did not do it.")
        }
        else {
          msg ("You did it!")
        }
      }
    }
  ]]></function>
  <function name="naphead_talk"><![CDATA[
    // THIS FUNCTION USES PLAY TEXT
    Boundary_Lock = true
    BoundaryLock
    if (game.active_play_text = null) {
      game.active_play_text = NewStringList()
    }
    // Check if the global list actually exists and has items
    if (ListCount(game.active_play_text) > 0) {
      // Pull the first item
      current_line = ListItem(game.active_play_text, 0)
      // Print it
      // If the line contains a break tag, split it and type separately
      msg ("current_line")
      // Remove it so the next loop gets the next line
      list remove (game.active_play_text, current_line)
      // Set a wait
      JS.eval ("$('#endWaitDiv').hide();")
      JS.eval ("$('#divOutput').append('<span id=\"temp-cursor\"> >> </span>');")
      wait {
        JS.eval ("$('#temp-cursor').remove();")
        anykey
      }
    }
    else {
      if (HasScript(game, "after_dialogue_script")) {
        do (game, "after_dialogue_script")
      }
    }
  ]]></function>
  <function name="asdfgtest"><![CDATA[
    msg ("Type \"asdfg\"")
    i = 0
    get input {
      for (i, 1, LengthOf(result)) {
        current_char = Mid(result, i, 1)
        if (not ListContains(altar.asdfglist, LCase(current_char))) {
          altar.asdfg_valid = false
        }
        else if (LengthOf(result) > 5) {
          altar.asdfg_valid = false
        }
        else if (result  <> "asdfg") {
          altar.asdfg_correct = false
        }
        else if (result = "asdfg") {
          altar.asdfg_correct = true
        }
      }
      on ready {
        if (altar.asdfg_valid = false) {
          msg ("You're imagining solutions that aren't real.")
        }
        else if (altar.asdfg_correct = false) {
          msg ("You know that's not it.")
        }
        else if (altar.asdfg_correct = true) {
          msg ("For some reason, that feels right.")
        }
        altar.asdfg_valid = true
        altar.asdfg_correct = false
      }
    }
  ]]></function>
  <function name="anykeyp"><![CDATA[
    Boundary_Lock = true
    BoundaryLock
    if (game.active_play_text = null) {
      game.active_play_text = NewStringList()
    }
    if (ListCount(game.active_play_text) > 0) {
      current_line = ListItem(game.active_play_text, 0)
      if (IsRegexMatch ("<br/>", current_line)) {
        parts = Split(current_line, "<br/>")
        foreach (p, parts) {
          msg (" ")
          msg (p)
        }
      }
      else {
        msg (" ")
        msg (current_line)
      }
      //
      list remove (game.active_play_text, current_line)
      //
      JS.eval ("$('#endWaitDiv').hide();")
      JS.eval ("$('#divOutput').append('<span id=\"temp-cursor\"> >> </span>');")
      wait {
        JS.eval ("$('#temp-cursor').remove();")
        anykeyp
      }
    }
    else {
      if (HasScript(game, "after_dialogue_script")) {
        game.active_play_text = null
        game.active_play_text = NewStringList ()
        game.nowhere_intro = null
        game.nowhere_intro = NewStringList ()
        do (game, "after_dialogue_script")
      }
    }
  ]]></function>
  <function name="intheworld"><![CDATA[
    Boundary_Lock = true
    BoundaryLock
    if (game.active_play_text = null) {
      game.active_play_text = NewStringList()
    }
    if (ListCount(game.active_play_text) > 0) {
      current_line = ListItem(game.active_play_text, 0)
      if (IsRegexMatch ("<br/>", current_line)) {
        parts = Split(current_line, "<br/>")
        foreach (p, parts) {
          TextFX_Typewriter (p, 45)
        }
      }
      else {
        TextFX_Typewriter (current_line, 45)
      }
      list remove (game.active_play_text, current_line)
      JS.eval ("$('#endWaitDiv').hide();")
      SetTimeout (5) {
        JS.eval ("$('#temp-cursor').remove();")
        on ready {
          intheworld
        }
      }
    }
    else {
      if (HasScript(game, "after_dialogue_script")) {
        do (game, "after_dialogue_script")
      }
    }
  ]]></function>
  <function name="aboutsnail"><![CDATA[
    if (ListCount(game.aboutsnailsweeper) > 0) {
      current_line = ListItem(game.aboutsnailsweeper, 0)
      msg (" ")
      msg (current_line)
      list remove (game.aboutsnailsweeper, current_line)
    }
    else {
      firsttime {
        msg ("Too slow and not magic enough for the average salesdriver, these machines were never all that popular. You've adjusted to the fact that you're never going to understand other people. <br/>")
        player.connection = player.connection+1
        game.aboutsnailsweeper = NewStringList()
        list add (game.aboutsnailsweeper, "Very few were ever even made. If this one were real, it might be the most exciting thing that ever happened to you. You've read everything there is to read about snailsweepers.")
        list add (game.aboutsnailsweeper, "Supposedly the original design actually swept up the trash and stored it in an extra-large storage nose. You think they made the right choice, going with a design that actually eats trash, but you wonder what the extra-large storage nose would have looked like.")
        list add (game.aboutsnailsweeper, "It won't outrun anyone, but it actually gets up to more than twice the speed of a snail its size would normally be in the wild. ")
        list add (game.aboutsnailsweeper, "Snailsweepers actually use less magic proportionate to their weight compared to machines being advertised today. To make Grazing Mode work, the underside has to be bow to stern living bristle. Supposedly it takes forever to cultivate properly. As a result, it doesn't strictly need to be magical throughout the chassis.")
        list add (game.aboutsnailsweeper, "You wonder how they got the lights to work. You're not sure what exactly is glowing or how that works without magic. You'd honestly thought the glowing was a magnets thing, but obviously that's not it.")
        list add (game.aboutsnailsweeper, "You wonder if you should even entertain the idea that this snailsweeper had belonged to someone else. You're pretty confident Calliope would be putting more than a few trees in your path if you were stealing something.")
      }
      otherwise {
        msg ("Too slow and not magic enough for the average salesdriver, these machines were never all that popular. You've adjusted to the fact that you're never going to understand other people.<br/>")
        game.aboutsnailsweeper = NewStringList()
        list add (game.aboutsnailsweeper, "Very few were ever even made. If this one were real, it might be the most exciting thing that ever happened to you. You've read everything there is to read about snailsweepers.")
        list add (game.aboutsnailsweeper, "Supposedly the original design actually swept up the trash and stored it in an extra-large storage nose. You think they made the right choice, going with a design that actually eats trash, but you wonder what the extra-large storage nose would have looked like.")
        list add (game.aboutsnailsweeper, "It won't outrun anyone, but it actually gets up to more than twice the speed of a snail its size would normally be in the wild. ")
        list add (game.aboutsnailsweeper, "Snailsweepers actually use less magic proportionate to their weight compared to machines being advertised today. To make Grazing Mode work, the underside has to be bow to stern living bristle. Supposedly it takes forever to cultivate properly. As a result, it doesn't strictly need to be magical throughout the chassis.")
        list add (game.aboutsnailsweeper, "You wonder how they got the lights to work. You're not sure what exactly is glowing or how that works without magic. You'd honestly thought the glowing was a magnets thing, but obviously that's not it.")
        list add (game.aboutsnailsweeper, "You wonder if you should even entertain the idea that this snailsweeper had belonged to someone else. You're pretty confident Calliope would be putting more than a few trees in your path if you were stealing something.")
      }
    }
  ]]></function>
  <function name="aboutyou"><![CDATA[
    if (ListCount(game.aboutyou) > 0) {
      current_line = ListItem(game.aboutyou, 0)
      msg (" ")
      msg (current_line)
      list remove (game.aboutyou, current_line)
    }
    else if (player.wantskettle) {
      msg ("Somehow being able to see your hands doesn't make them look more real.")
      game.aboutyou = NewStringList()
      list add (game.aboutyou, "You wonder what your voice sounds like. You assume it's different from the last time you heard it.")
      list add (game.aboutyou, "You stare at the curtain until your eyes sting but your eyelids just keep getting wider.")
      list add (game.aboutyou, "You can feel the rumble of bristles breaking down trash beneath, and you sort of wish you were out there belly-down on the ground, too.")
      list add (game.aboutyou, "You try to push the hair out of your face, but that just gets it in your eyes.")
      list add (game.aboutyou, "You wonder if you should've become a wizard. An empty magic tank is only the latest problem in your life that being a wizard could have solved.")
    }
    else {
      player.wantskettle = true
      player.curiosity = player.curiosity+1
      msg ("Somehow being able to see your hands doesn't make them look more real.")
      game.aboutyou = NewStringList()
      list add (game.aboutyou, "You wonder what your voice sounds like. You assume it's different from the last time you heard it.")
      list add (game.aboutyou, "You stare at the curtain until your eyes sting but your eyelids just keep getting wider.")
      list add (game.aboutyou, "You can feel the rumble of bristles breaking down trash beneath, and you sort of wish you were out there belly-down on the ground, too.")
      list add (game.aboutyou, "You try to push the hair out of your face, but that just gets it in your eyes.")
      list add (game.aboutyou, "You wonder if you should've become a wizard. An empty magic tank is only the latest problem in your life that being a wizard could have solved.")
    }
  ]]></function>
  <function name="introendcredits"><![CDATA[
    SetForegroundColour ("Aqua")
    SetWebFontName ("Press Start 2P")
    JS.uiHide ("#txtCommandDiv")
    if (game.introendcredits = 0) {
      JS.eval ("window.cachedAudio8.play();")
      SetTimeout (9) {
        PrintCentered ("Thank you for visiting Grotto Vale.")
        SetTimeout (2) {
          PrintCentered ("Thank you for visiting the Calliope.")
          SetTimeout (2) {
            game.introendcredits = 1
            SetFontName ("Lucida Console")
            SetForegroundColour ("White")
            introendcredits
          }
        }
      }
    }
    else if (game.introendcredits = 1) {
      if (player.wantskettle) {
        SetTimeout (2) {
          PrintCentered ("<br/>Thank you for being curious. ")
          on ready {
            SetFontName ("'Lucida Console', Monaco, monospace")
            PrintCentered ("[You found the kettle.]")
            PrintCentered (" ")
          }
          on ready {
            SetWebFontName ("Press Start 2P")
            on ready {
              SetTimeout (2) {
                PrintCentered (" ")
                game.introendcredits = 11
                introendcredits
              }
            }
          }
        }
      }
      else {
        on ready {
          SetTimeout (2) {
            PrintCentered (". . . .")
            game.introendcredits = 11
            introendcredits
          }
        }
      }
    }
    else if (game.introendcredits = 2) {
      PrintCentered ("Carrying you and your burdens through the long night")
      SetTimeout (2) {
        PrintCentered (". . . . so nobody else has to.")
        SetTimeout (2) {
          PrintCentered ("You can count on your snailsweeper. <br/>")
          SetTimeout (1) {
            img_url = "https://i.imgur.com/qwEjfz4.jpeg"
            JS.eval ("var newDiv = $('<div style=\"text-align:center; margin:10px 0;\"></div>'); var img = $('<img src=\"" + img_url + "\" style=\"display:block; margin:0 auto; max-width:100%; max-height:300px;\" />'); newDiv.append(img); var last = $('#divOutput div').last(); if (last.length) { last.after(newDiv); } else { $('#divOutput').append(newDiv); } setTimeout(function() { $('#divOutput').scrollTop($('#divOutput')[0].scrollHeight); }, 50);")
            PrintCentered ("<br/>To be continued . . . .")
            on ready {
              PrintCentered (" ")
              game.introendcredits = 3
              introendcredits
            }
          }
        }
      }
    }
    else if (game.introendcredits = 3) {
      SetTimeout (2) {
        SetFontName ("Lucida Console")
        SetForegroundColour ("White")
        on ready {
          msg ("<br/>[Press any key for credits.]<br/>")
        }
        JS.eval ("$('#endWaitDiv').hide();")
        SetFontSize (14)
        on ready {
          wait {
            msg ("<br/>Onion Hugs: \"Getting Started\"<br/>")
            SetTimeout (2) {
              SetFontSize (12)
              msg ("<br/>creation and sole responsibility of<br/>ALEX BIRCH (normaltunanoises)<br/>")
              SetTimeout (3) {
                msg ("<br/>\"the sound of dial up internet\"<br/>by WTERMINI via FREESOUND.ORG, CC0.<br/><br/>old radio noise<br/>by DRNI via FREESOUND.ORG. CC0.<br/><br/>\"as silent as its shadow\"<br/>by ROLLS ROYCE, 1935. Public Domain.<br/><br/>\"touring or detouring\"<br/>by MARMON MOTOR CAR COMPANY, 1920s. Public Domain.<br/>")
                SetTimeout (4) {
                  msg ("<br/>made in QUEST 5.9<br/>")
                  SetTimeout (2) {
                    msg ("<br/>other software used: <br/>AUDACITY<br/>KOALA SAMURAI<br/>INKSCAPE<br/>MS PAINT<br/>WINDOWS MOVIE MAKER<br/>EZGIF.COM<br/>")
                    SetTimeout (3) {
                      msg ("<br/>Thank you.<br/>")
                      SetTimeout (5) {
                        msg ("DISCONNECTED")
                        finish
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    else if (game.introendcredits = 111) {
      if (player.lcbcuddles=1) {
        SetTimeout (1) {
          PrintCentered ("Thank you for lingering.")
          on ready {
            SetFontName ("'Lucida Console', Monaco, monospace")
            PrintCentered ("[You spent more time inside the shell.]")
            PrintCentered (" ")
          }
          on ready {
            SetWebFontName ("Press Start 2P")
            on ready {
              SetTimeout (2) {
                PrintCentered (" ")
                game.introendcredits = 1111
                introendcredits
              }
            }
          }
        }
      }
      else {
        on ready {
          SetTimeout (2) {
            PrintCentered (". . . .")
            game.introendcredits = 111
            introendcredits
          }
        }
      }
    }
    else if (game.introendcredits = 1111) {
      if (player.askedruok=1) {
        SetTimeout (1) {
          PrintCentered ("Thank you for keeping your promises. So far.")
          SetFontName ("'Lucida Console', Monaco, monospace")
          PrintCentered ("[You chose your magic words wisely.]")
          PrintCentered (" ")
          on ready {
            SetWebFontName ("Press Start 2P")
            on ready {
              SetTimeout (2) {
                PrintCentered (" ")
                game.introendcredits = 2
                introendcredits
              }
            }
          }
        }
      }
      else {
        on ready {
          SetTimeout (2) {
            PrintCentered (". . . . ")
            SetTimeout (4) {
              game.introendcredits = 2
              introendcredits
            }
          }
        }
      }
    }
    else if (game.introendcredits = 11) {
      if (player.rememberverb) {
        SetTimeout (2) {
          PrintCentered ("<br/>Thank you for having care. ")
          on ready {
            SetFontName ("'Lucida Console', Monaco, monospace")
            PrintCentered ("[You surfaced some memories.]")
            PrintCentered (" ")
          }
          on ready {
            SetWebFontName ("Press Start 2P")
            on ready {
              SetTimeout (2) {
                PrintCentered (" ")
                game.introendcredits = 111
                introendcredits
              }
            }
          }
        }
      }
      else {
        on ready {
          SetTimeout (2) {
            PrintCentered (". . . .")
            game.introendcredits = 11
            introendcredits
          }
        }
      }
    }
  ]]></function>
  <function name="BackToShell"><![CDATA[
    msg (" ")
    if (game.shellventory="4") {
      HelperOpenObject (Shlvl One)
      MoveObject (Snailsweeper Operation Manual, Shlvl One)
      MoveObject (Latest Pages, Shlvl One)
      MoveObject (Pen Set, Shlvl One)
      MoveObject (Hat with no eyes, Shlvl One)
      MoveObject (Loobert Chewbert Boobert, Shlvl One)
      game.nowhere_intro = NewStringList()
      game.active_play_text = NewStringList()
      list add (game.nowhere_intro, "You can keep doing what you're doing, or pick something else out of the pile:")
      list add (game.nowhere_intro, " ")
      list add (game.nowhere_intro, "[Fuzzy ball of PRESERVATIVE] <br/>[Tube of INSPIRATION]<br/>[Official Grull & Trawl Snailsweeper Operation MANUAL] <br/>[Latest PAGES] <br/>[PEN and well] <br/>[HAT without eyes] <br/>[LOOBERT CHEWBERT BOOBERT]<br/>")
      list add (game.nowhere_intro, "You can DIG in the trash if you want, and you can go back to the CONSOLE when you're done.")
      foreach (item, game.nowhere_intro) {
        list add (game.active_play_text, item)
      }
      on ready {
        anykey
      }
      game.after_dialogue_script => {
        game.Boundary_Lock = false
        BoundaryUnlock
        JS.uiShow ("#txtCommandDiv")
      }
    }
    else if (game.shellventory="2") {
      HelperOpenObject (Shlvl One)
      game.nowhere_intro = NewStringList()
      game.active_play_text = NewStringList()
      list add (game.nowhere_intro, "You can keep doing what you're doing, or pick something else out of the pile:")
      list add (game.nowhere_intro, " ")
      list add (game.nowhere_intro, "[Fuzzy ball of PRESERVATIVE].<br/>[Tube of INSPIRATION]<br/>Latest [PAGES]<br/>[Snailsweeper MANUAL]")
      list add (game.nowhere_intro, "You can dig DEEP to find more, or you can go back to the CONSOLE.")
      foreach (item, game.nowhere_intro) {
        list add (game.active_play_text, item)
      }
      on ready {
        anykey
      }
      game.after_dialogue_script => {
        game.Boundary_Lock = false
        BoundaryUnlock
        JS.uiShow ("#txtCommandDiv")
      }
    }
    else if (game.shellventory="3") {
      HelperOpenObject (Shlvl One)
      game.nowhere_intro = NewStringList()
      game.active_play_text = NewStringList()
      list add (game.nowhere_intro, "You can keep doing what you're doing, or pick something else out of the pile:")
      list add (game.nowhere_intro, " ")
      list add (game.nowhere_intro, "[Fuzzy ball of PRESERVATIVE].<br/>[Tube of INSPIRATION]<br/>[Latest PAGES]<br/>[Snailsweeper MANUAL]<br/>[HAT without eyes]<br/>[PEN and well]")
      list add (game.nowhere_intro, "You can dig DEEPER to find more, or you can go back to the CONSOLE.")
      foreach (item, game.nowhere_intro) {
        list add (game.active_play_text, item)
      }
      on ready {
        anykey
      }
      game.after_dialogue_script => {
        game.Boundary_Lock = false
        BoundaryUnlock
        JS.uiShow ("#txtCommandDiv")
      }
    }
    else {
      HelperOpenObject (Shlvl One)
      game.active_play_text = NewStringList()
      game.nowhere_intro = NewStringList()
      list add (game.nowhere_intro, "You can keep doing what you're doing, or pick something else out of the pile:")
      list add (game.nowhere_intro, "[Fuzzy ball of PRESERVATIVE].<br/>[Tube of INSPIRATION]")
      list add (game.nowhere_intro, "You can DIG to find more, or you can go back to the CONSOLE.")
      foreach (item, game.nowhere_intro) {
        list add (game.active_play_text, item)
      }
      on ready {
        anykey
      }
      game.after_dialogue_script => {
        game.Boundary_Lock = false
        BoundaryUnlock
        JS.uiShow ("#txtCommandDiv")
      }
    }
  ]]></function>
  <function name="ConsoleIntroEnd"><![CDATA[
    if (not game.consoleintroed) {
      game.nowhere_intro = NewStringList()
      list add (game.nowhere_intro, "<br/>You're having a realization.")
      list add (game.nowhere_intro, "You can't hear the leaves against the shell anymore.")
      list add (game.nowhere_intro, "It might be time to [RAISE] the [CURTAINS].")
      foreach (item, game.nowhere_intro) {
        list add (game.active_play_text, item)
      }
      on ready {
        JS.eval ("if (window.cachedAudio7) { window.cachedAudio7.pause(); window.cachedAudio7.currentTime = 0; }")
        anykey
        MakeObjectVisible (Nap Head)
      }
      game.after_dialogue_script => {
        game.Boundary_Lock = false
        BoundaryUnlock
        JS.uiShow ("#txtCommandDiv")
        game.intro_end = true
        game.introendconsole = false
        game.consoleintroed = true
        game.inendconsoletrigger = false
      }
    }
    else if (game.consoleintroed) {
      if (player.wantskettle) {
        HelperCloseObject (Shlvl Three)
        HelperCloseObject (Shlvl Two)
        HelperCloseObject (Shlvl One)
        msg ("You see the [MAGIC LIGHT], the [RUN LEVER], the [TILT SHIFT], the [Steering VALVES], the [NAV POINTER], the [COLOR WHEEL], the [CLAVIature], and the [KETTLE].<br/> <br/>Most of it looks powered down, but you can still learn more [ABOUT] them.")
        MakeObjectVisible (Kettle)
        game.inendconsoletrigger = false
      }
      else {
        HelperCloseObject (Shlvl Three)
        HelperCloseObject (Shlvl Two)
        HelperCloseObject (Shlvl One)
        msg ("You see the [MAGIC LIGHT], the [RUN LEVER], the [TILT SHIFT], the [STEERING VALVES], the [NAV POINTER], the [COLOR WHEEL], the [CLAVIATURE].<br/> <br/>Most of it looks powered down, but you can still learn more [ABOUT] them.")
        game.inendconsoletrigger = false
      }
    }
  ]]></function>
  <function name="pc_statupdate">
    game.fear_impact = game.player_impact-player.host_fearmod
    player.host_fear = 100-game.fear_impact
    game.player_impact = player.curiosity+player.care+player.connection
    game.lonely_impact = game.player_impact-player.host_lonelymod
    player.host_lonely = 100-game.lonely_impact
    player.PingRate = player.PingBase-player.connection
    // curiosity, care, connection cap out at 50 total, for 10 potential points for each chapter of the game. 5 of those should be major events, 5 minor.
    // host lonelymod should be 50 at minimum and go up from there and not go down. More lonelymod more lonely.
    // host fearmod should be -50 at minimum and spike up from there. More fearmod more fear.
  </function>
  <function name="UpToConsole" parameters="shlvl"><![CDATA[
    if (shlvl = 4) {
      if (game.shellup4=3) {
        // rewrite this one
        game.shlvl_three = true
        MoveObject (player, Shlvl One)
        game.shellventory = "4"
        game.shellup4 = 3
        game.active_play_text = NewStringList()
        game.nowhere_intro = NewStringList()
        list add (game.nowhere_intro, "You start pulling yourself out of your trash nest.")
        list add (game.nowhere_intro, "Because apparently you have no control over your life.")
        foreach (item, game.nowhere_intro) {
          list add (game.active_play_text, item)
        }
        on ready {
          anykey
        }
        game.after_dialogue_script => {
          game.Boundary_Lock = false
          BoundaryUnlock
          JS.uiShow ("#txtCommandDiv")
        }
      }
      else if (game.shellup4=2) {
        // rewrite this one
        game.shlvl_three = true
        MoveObject (player, Shlvl One)
        game.shellventory = "4"
        game.shellup4 = 3
        game.active_play_text = NewStringList()
        game.nowhere_intro = NewStringList()
        list add (game.nowhere_intro, "Why the rush to get back to the CONSOLE?")
        list add (game.nowhere_intro, "Don't you like it in here?")
        list add (game.nowhere_intro, "Of course you do. You love trash.")
        foreach (item, game.nowhere_intro) {
          list add (game.active_play_text, item)
        }
        on ready {
          anykey
        }
        game.after_dialogue_script => {
          game.Boundary_Lock = false
          BoundaryUnlock
          JS.uiShow ("#txtCommandDiv")
        }
      }
      else if (game.shellup4=1) {
        game.shlvl_three = true
        MoveObject (player, Shlvl One)
        game.shellventory = "4"
        game.shellup4 = 2
        game.active_play_text = NewStringList()
        game.nowhere_intro = NewStringList()
        list add (game.nowhere_intro, "What?")
        list add (game.nowhere_intro, "Really?")
        list add (game.nowhere_intro, "Do you really need to go back to the CONSOLE already?")
        foreach (item, game.nowhere_intro) {
          list add (game.active_play_text, item)
        }
        on ready {
          anykey
        }
        game.after_dialogue_script => {
          game.Boundary_Lock = false
          BoundaryUnlock
          JS.uiShow ("#txtCommandDiv")
        }
      }
    }
    else if (shlvl = 3) {
      if (game.shellup3=3) {
        if (game.shlvl_three) {
          game.shlvl_two = true
          game.shlvl_three = false
          game.shellup3 = 3
          game.active_play_text = NewStringList()
          game.nowhere_intro = NewStringList()
          list add (game.nowhere_intro, ". . . . Fine.")
          list add (game.nowhere_intro, "But you're not going to hurry.")
          foreach (item, game.nowhere_intro) {
            list add (game.active_play_text, item)
          }
          on ready {
            anykey
          }
          game.after_dialogue_script => {
            game.Boundary_Lock = false
            BoundaryUnlock
            JS.uiShow ("#txtCommandDiv")
          }
        }
      }
      else if (game.shellup3=2) {
        if (game.shlvl_three) {
          game.shlvl_two = true
          game.shlvl_three = false
          game.shellup3 = 3
          game.active_play_text = NewStringList()
          game.nowhere_intro = NewStringList()
          list add (game.nowhere_intro, "It's just that this is your favorite trash pile so far.")
          list add (game.nowhere_intro, "You know you have to get back to the CONSOLE, but. . . .")
          foreach (item, game.nowhere_intro) {
            list add (game.active_play_text, item)
          }
          on ready {
            anykey
          }
          game.after_dialogue_script => {
            game.Boundary_Lock = false
            BoundaryUnlock
            JS.uiShow ("#txtCommandDiv")
          }
        }
      }
      else if (game.shellup3=1) {
        if (game.shlvl_three) {
          game.shlvl_two = true
          game.shlvl_three = false
          game.shellup3 = 2
          game.active_play_text = NewStringList()
          game.nowhere_intro = NewStringList()
          list add (game.nowhere_intro, "You reluctantly start to get moving.")
          list add (game.nowhere_intro, "You're deep in the trash, so it doesn't go great.")
          list add (game.nowhere_intro, "....Yeah, if you want to get back to the CONSOLE, you're going to have to try that again.")
          foreach (item, game.nowhere_intro) {
            list add (game.active_play_text, item)
          }
          on ready {
            anykey
          }
          game.after_dialogue_script => {
            game.Boundary_Lock = false
            BoundaryUnlock
            JS.uiShow ("#txtCommandDiv")
          }
        }
      }
    }
    else if (shlvl = 2) {
      if (game.shellup2=3) {
        // rewrite this one
        on ready {
          game.shlvl_two = false
          game.shlvl_one = true
          game.shellup2 = 3
        }
        game.active_play_text = NewStringList()
        game.nowhere_intro = NewStringList()
        list add (game.nowhere_intro, "It's easy to get comfortable under all this trash.")
        list add (game.nowhere_intro, "Is it ever going to get easier to climb back out?")
        foreach (item, game.nowhere_intro) {
          list add (game.active_play_text, item)
        }
        on ready {
          anykey
        }
        game.after_dialogue_script => {
          game.Boundary_Lock = false
          BoundaryUnlock
          JS.uiShow ("#txtCommandDiv")
        }
      }
      else if (game.shellup2=2) {
        // rewrite this one
        on ready {
          game.shlvl_two = false
          game.shlvl_one = true
          game.shellup2 = 3
        }
        game.active_play_text = NewStringList()
        game.nowhere_intro = NewStringList()
        list add (game.nowhere_intro, "You don't like how hard it is to do this.")
        list add (game.nowhere_intro, "Almost like the trash doesn't want you to go back to the CONSOLE.")
        foreach (item, game.nowhere_intro) {
          list add (game.active_play_text, item)
        }
        on ready {
          anykey
        }
        game.after_dialogue_script => {
          game.Boundary_Lock = false
          BoundaryUnlock
          JS.uiShow ("#txtCommandDiv")
        }
      }
      else if (game.shellup2=1) {
        on ready {
          game.shlvl_two = false
          game.shlvl_one = true
          game.shellup2 = 2
        }
        game.active_play_text = NewStringList()
        game.nowhere_intro = NewStringList()
        list add (game.nowhere_intro, "You start to pull yourself back out of the trash....")
        list add (game.nowhere_intro, "....It's slow going.")
        list add (game.nowhere_intro, "All this to get back to the CONSOLE.")
        foreach (item, game.nowhere_intro) {
          list add (game.active_play_text, item)
        }
        on ready {
          anykey
        }
        game.after_dialogue_script => {
          game.Boundary_Lock = false
          BoundaryUnlock
          JS.uiShow ("#txtCommandDiv")
        }
      }
    }
    else if (shlvl =1) {
      if (game.shellup1=1) {
        on ready {
          HelperCloseObject (Shlvl Three)
          HelperCloseObject (Shlvl Two)
          HelperCloseObject (Shlvl One)
        }
        game.active_play_text = NewStringList()
        game.nowhere_intro = NewStringList()
        list add (game.nowhere_intro, "You clamber back into the driver's seat.")
        list add (game.nowhere_intro, "You can look at that CONSOLE whenever you want now.")
        foreach (item, game.nowhere_intro) {
          list add (game.active_play_text, item)
        }
        on ready {
          anykey
        }
        game.after_dialogue_script => {
          game.active_play_text = NewStringList()
          game.nowhere_intro = NewStringList()
          msg ("> The snailsweeper slowly starts to move!")
          MoveObject (player, Snailsweeper)
          game.Boundary_Lock = false
          BoundaryUnlock
          JS.uiShow ("#txtCommandDiv")
        }
        on ready {
          game.shlvl_one = false
        }
      }
    }
  ]]></function>
  <function name="driverseat"><![CDATA[
    if (Snailsweeper.driverseat=30) {
      if (not GetBoolean(game, "intro_end")) {
        game.active_play_text = NewStringList()
        game.nowhere_intro = NewStringList()
        player.connection = player.connection+1
        player.curiosity = player.curiosity+1
        list add (game.nowhere_intro, "Sitting in the driver's seat, you can't help but relax.")
        list add (game.nowhere_intro, "You're content to stay here a moment..")
        list add (game.nowhere_intro, "Will you stay?")
        list add (game.nowhere_intro, "YES/NO")
        game.after_dialogue_script => {
          Boundary_Lock = False
          BoundaryUnlock
          JS.uiShow ("#txtCommandDiv")
          get input {
            if (LCase(result) = "yes") {
              game.active_play_text = NewStringList()
              game.nowhere_intro = NewStringList()
              player.connection = player.connection+1
              player.curiosity = player.curiosity+1
              list add (game.nowhere_intro, "It's incredibly pleasant, riding in a snailsweeper.")
              list add (game.nowhere_intro, "The seat is comfortable. Everything is clean.")
              list add (game.nowhere_intro, "You don't even mind the smell of trees.")
              list add (game.nowhere_intro, "Even without seeing them, with the curtains drawn, the smell is a green smell. ")
              list add (game.nowhere_intro, "An energetic, sun-kissed green kind of smell, just this side of stinging the nostrils.")
              list add (game.nowhere_intro, "It's a nice smell. Smells awake.")
              list add (game.nowhere_intro, "Smells like. . . . connection.")
              list add (game.nowhere_intro, "Like you're connected to something vast and breathing.")
              list add (game.nowhere_intro, "Like you have everyone in the world to share roots with.")
              list add (game.nowhere_intro, "Even if you're not supposed to.")
              list add (game.nowhere_intro, "Even though you're not really one of them at all.")
              list add (game.nowhere_intro, ". . . .")
              list add (game.nowhere_intro, "You're pretty sure real trees smell the same way. ")
              list add (game.nowhere_intro, "At this point you've smelled more visions than actual trees in your life.")
              list add (game.nowhere_intro, "It's hard to keep track of what was real and what wasn't.")
              list add (game.nowhere_intro, "The visions aren't entirely to blame.")
              list add (game.nowhere_intro, "Once something's in the past, it's hard not to smudge the details.")
              list add (game.nowhere_intro, "Maybe you're not giving Calliope's memory enough credit. ")
              list add (game.nowhere_intro, ". . . .You wonder if the important parts are still the same.")
              list add (game.nowhere_intro, ". . . .You wonder what you still [REMEMBER].")
              list add (game.nowhere_intro, ". . . . ")
              list add (game.nowhere_intro, "Somehow, the sound of leaves is making you feel restless again.")
              game.after_dialogue_script => {
                Boundary_Lock = False
                BoundaryUnlock
                JS.uiShow ("#txtCommandDiv")
                Snailsweeper.driverstext = true
                set (Snailsweeper, "driverseat", Snailsweeper.driverseat+1)
              }
              foreach (item, game.nowhere_intro) {
                list add (game.active_play_text, item)
              }
              on ready {
                anykey
              }
            }
            else {
              Boundary_Lock = False
              BoundaryUnlock
              JS.uiShow ("#txtCommandDiv")
              Snailsweeper.driverstext = true
              set (Snailsweeper, "driverseat", Snailsweeper.driverseat+1)
            }
          }
        }
        foreach (item, game.nowhere_intro) {
          list add (game.active_play_text, item)
        }
        on ready {
          anykey
        }
      }
      else if (game, "intro_end") {
        set (Snailsweeper, "driverseat", Snailsweeper.driverseat+1)
      }
    }
  ]]></function>
</asl>