Add a monster stuffie to the lobby
[mudsync.git] / worlds / bricabrac.scm
index 8ea7451a7701608bf32d132dc514bc794a0adc02..dfd62ebc21ae899ec2e9306ea23993b23c9e8798 100644 (file)
@@ -1,5 +1,5 @@
 ;;; Mudsync --- Live hackable MUD
 ;;; Mudsync --- Live hackable MUD
-;;; Copyright © 2016, 2017 Christopher Allan Webber <cwebber@dustycloud.org>
+;;; Copyright © 2016, 2017 Christine Lemmer-Webber <cwebber@dustycloud.org>
 ;;;
 ;;; This file is part of Mudsync.
 ;;;
 ;;;
 ;;; This file is part of Mudsync.
 ;;;
@@ -256,18 +256,17 @@ character.\n")))
    ;; NPC: hotel owner
    ('lobby:hotel-owner
     <chatty-npc> 'lobby
    ;; NPC: hotel owner
    ('lobby:hotel-owner
     <chatty-npc> 'lobby
-    #:name "a frumpy fellow"
+    #:name "a languid lady"
     #:desc
     #:desc
-    '((p "  Whoever this is, they looks totally exhausted.  They're
+    '((p "  Whoever this is, she looks totally exhausted.  She's
 collapsed into the only comfortable looking chair in the room and you
 collapsed into the only comfortable looking chair in the room and you
-don't get the sense that they're likely to move any time soon.
-  You notice they're wearing a sticker badly adhesed to their clothing
-which says \"Hotel Proprietor\", but they look so disorganized that you
-think that can't possibly be true... can it?
-  Despite their exhaustion, you sense they'd be happy to chat with you,
+don't get the sense that she's likely to move any time soon.
+  Attached to her frumpy dress is a barely secured pin which says
+\"Hotel Proprietor\", but she looks so disorganized that you think
+that can't possibly be true... can it?
+  Despite her exhaustion, you sense she'd be happy to chat with you,
 though the conversation may be a bit one sided."))
 though the conversation may be a bit one sided."))
-    #:goes-by '("frumpy fellow" "fellow"
-                "Chris Webber"  ; heh, did you rtfc?  or was it so obvious?
+    #:goes-by '("languid lady" "lady"
                 "hotel proprietor" "proprietor")
     #:catchphrases hotel-owner-grumps)
    ;; Object: Sign
                 "hotel proprietor" "proprietor")
     #:catchphrases hotel-owner-grumps)
    ;; Object: Sign
@@ -425,7 +424,17 @@ this general shape in the 1990s."
     #:goes-by '("orange cartoon cat phone" "orange cartoon cat telephone"
                 "orange cat phone" "orange cat telephone"
                 "cartoon cat phone" "cartoon cat"
     #:goes-by '("orange cartoon cat phone" "orange cartoon cat telephone"
                 "orange cat phone" "orange cat telephone"
                 "cartoon cat phone" "cartoon cat"
-                "cat phone" "cat telephone" "phone" "telephone"))))
+                "cat phone" "cat telephone" "phone" "telephone"))
+   ('lobby:monster-stuffie
+    <gameobj> 'lobby
+    #:name "an off-brand monster stuffie"
+    #:desc "It's an off brand monster stuffed animal that looks, well kinda
+like a popular character you've seen in a video game, but there's been a very
+thin attempt to make it look like something different... mostly by changing
+the shape of the ears.  It's cute though!"
+    #:take-me? #t
+    #:goes-by '("monster stuffie" "monster" "stuffed animal" "stuffed monster"
+               "off-brand monster stuffie" "stuffie" "monster stuffie"))))
 
 
 \f
 
 
 \f
@@ -488,6 +497,13 @@ labeled \"RL02.5\".")
 
 (define lobby-map-text
   "\
 
 (define lobby-map-text
   "\
+
+                        .----+++++----.
+                        |  :       :  |
+                        +  : north :  +
+                        |  :  hall :  |
+                        +  :       :  +
+                        |_ : _____ : _|
                         |  :       :  |
   .----------.----------.  :   &   :  .----------.----------.
   | computer |          |& :YOU ARE: &|  smoking | *UNDER*  |
                         |  :       :  |
   .----------.----------.  :   &   :  .----------.----------.
   | computer |          |& :YOU ARE: &|  smoking | *UNDER*  |
@@ -500,6 +516,7 @@ labeled \"RL02.5\".")
                           '---------'")
 
 (define grand-hallway
                           '---------'")
 
 (define grand-hallway
+
   (lol
    ('grand-hallway
     <room> #f
   (lol
    ('grand-hallway
     <room> #f
@@ -514,6 +531,9 @@ that's all about?")
 room\", while a door to the west is labeled \"playroom\"."))
     #:exits
     (list (make <exit>
 room\", while a door to the west is labeled \"playroom\"."))
     #:exits
     (list (make <exit>
+           #:name "north"
+           #:to 'north-hall)
+         (make <exit>
             #:name "south"
             #:to 'lobby)
           (make <exit>
             #:name "south"
             #:to 'lobby)
           (make <exit>
@@ -597,6 +617,243 @@ platter!  It has \"RL02.5\" written on it.  It looks kind of loose."
 ;;; Playroom
 ;;; --------
 
 ;;; Playroom
 ;;; --------
 
+(define-actor <rgb-machine> (<gameobj>)
+  ((cmd-run rgb-machine-cmd-run)
+   (cmd-reset rgb-machine-cmd-reset))
+  (commands
+   #:allocation #:each-subclass
+   #:init-thunk (build-commands
+                 (("run" "start") ((direct-command cmd-run)))
+                 ("reset" ((direct-command cmd-reset)))))
+  (resetting #:init-value #f
+             #:accessor .resetting)
+  ;; used to reset, and to kick off the first item in the list
+  (rgb-items #:init-keyword #:rgb-items
+             #:accessor .rgb-items))
+
+(define (rgb-machine-cmd-run rgb-machine message . _)
+  (define player (message-from message))
+  (<-wait player 'tell
+          #:text '("You start the rube goldberg machine."))
+  (<-wait (gameobj-loc rgb-machine) 'tell-room
+          #:text `(,(mbody-val (<-wait player 'get-name))
+                   " runs the rube goldberg machine.")
+          #:exclude player)
+  (8sleep 1)
+  (match (.rgb-items rgb-machine)
+    ((first-item rest ...)
+     (<- (dyn-ref rgb-machine first-item) 'trigger))))
+
+(define (rgb-machine-cmd-reset rgb-machine message . _)
+  (define player (message-from message))
+  (cond
+   ((not (.resetting rgb-machine))
+    (set! (.resetting rgb-machine) #t)
+    (<-wait player 'tell
+            #:text '("You reset the rube goldberg machine."))
+    (<-wait (gameobj-loc rgb-machine) 'tell-room
+            #:text `(,(mbody-val (<-wait player 'get-name))
+                     " resets the rube goldberg machine.")
+            #:exclude player)
+    (<-wait (gameobj-loc rgb-machine) 'tell-room
+            #:text '("From a panel in the wall, a white gloved mechanical "
+                     "arm reaches out to reset all the "
+                     "rube goldberg components."))
+    (8sleep (/ 1 2))
+    (for-each
+     (lambda (rgb-item)
+       (<- (dyn-ref rgb-machine rgb-item) 'reset)
+       (8sleep (/ 1 2)))
+     (.rgb-items rgb-machine))
+    (<- (gameobj-loc rgb-machine) 'tell-room
+        #:text "The machine's mechanical arm retreats into the wall!")
+    (set! (.resetting rgb-machine) #f))
+   (else
+    (<-wait player 'tell
+            #:text '("But it's in the middle of resetting right now!")))))
+
+(define-actor <rgb-item> (<gameobj>)
+  ((trigger rgb-item-trigger)
+   (reset rgb-item-reset))
+  (invisible? #:init-value #t)
+  (steps #:init-keyword #:steps
+         #:accessor .steps)
+  (triggers-as #:init-value #f
+               #:init-keyword #:triggers-as
+               #:getter .triggers-as)
+  (reset-msg #:init-keyword #:reset-msg
+             #:getter .reset-msg)
+  ;; States: ready -> running -> ran
+  (state #:init-value 'ready
+         #:accessor .state))
+
+
+(define (rgb-item-trigger rgb-item message . _)
+  (define room (gameobj-loc rgb-item))
+  (case (.state rgb-item)
+    ((ready)
+     ;; Set state to running
+     (set! (.state rgb-item) 'running)
+
+     ;; Loop through all steps
+     (for-each
+      (lambda (step)
+        (match step
+          ;; A string?  That's the description of what's happening, tell players
+          ((? string? str)
+           (<- room 'tell-room #:text str))
+          ;; A number?  Sleep for that many secs
+          ((? number? num)
+           (8sleep num))
+          ;; A symbol?  That's another gameobj to look up dynamically
+          ((? symbol? sym)
+           (<- (dyn-ref rgb-item sym) 'trigger
+               #:triggered-by (.triggers-as rgb-item)))
+          (_ (throw 'unknown-step-type
+                    "Don't know how to process rube goldberg machine step type?"
+                    #:step step))))
+      (.steps rgb-item))
+
+     ;; We're done! Set state to ran
+     (set! (.state rgb-item) 'ran))
+
+    (else
+     (<- room 'tell-room
+         #:text `("... but " ,(slot-ref rgb-item 'name)
+                  " has already been triggered!")))))
+
+(define (rgb-item-reset rgb-item message . _)
+  (define room (gameobj-loc rgb-item))
+  (case (.state rgb-item)
+    ((ran)
+     (set! (.state rgb-item) 'ready)
+     (<- room 'tell-room
+         #:text (.reset-msg rgb-item)))
+    ((running)
+     (<- room 'tell-room
+         #:text `("... but " ,(slot-ref rgb-item 'name)
+                  " is currently running!")))
+    ((ready)
+     (<- room 'tell-room
+         #:text `("... but " ,(slot-ref rgb-item 'name)
+                  " has already been reset.")))))
+
+(define-actor <rgb-kettle> (<rgb-item>)
+  ((trigger rgb-kettle-trigger)
+   (reset rgb-kettle-reset))
+  (heated #:accessor .heated
+          #:init-value #f)
+  (filled #:accessor .filled
+          #:init-value #f))
+
+(define* (rgb-kettle-trigger rgb-item message #:key triggered-by)
+  (define room (gameobj-loc rgb-item))
+  (if (not (eq? (.state rgb-item) 'ran))
+      (begin
+        (match triggered-by
+          ('water-demon
+           (set! (.state rgb-item) 'running)
+           (set! (.filled rgb-item) #t))
+          ('quik-heater
+           (set! (.state rgb-item) 'running)
+           (set! (.heated rgb-item) #t)))
+        (when (and (.filled rgb-item)
+                   (.heated rgb-item))
+          (<- room 'tell-room
+              #:text '((i "*kshhhhhh!*")
+                       " The water has boiled!"))
+          (8sleep .25)
+          (set! (.state rgb-item) 'ran)
+          ;; insert a cup of hot tea in the room
+          (create-gameobj <hot-tea> (gameobj-gm rgb-item) room)
+          (<- room 'tell-room
+              #:text '("The machine pours out a cup of hot tea! "
+                       "Looks like the machine finished!"))))
+      (<- room 'tell-room
+         #:text `("... but " ,(slot-ref rgb-item 'name)
+                  " has already been triggered!"))))
+
+(define (rgb-kettle-reset rgb-item message . rest-args)
+  (define room (gameobj-loc rgb-item))
+  (when (eq? (.state rgb-item) 'ran)
+    (set! (.heated rgb-item) #f)
+    (set! (.filled rgb-item) #f))
+  (apply rgb-item-reset rgb-item message rest-args))
+
+(define-actor <tinfoil-hat> (<gameobj>)
+  ((cmd-wear tinfoil-hat-wear))
+  (contained-commands
+   #:allocation #:each-subclass
+   #:init-thunk (build-commands
+                 ("wear" ((direct-command cmd-wear))))))
+
+(define (tinfoil-hat-wear tinfoil-hat message . _)
+  (<- (message-from message) 'tell
+      #:text '("You put on the tinfoil hat, and, to be perfectly honest with you "
+               "it's a lot harder to take you seriously.")))
+
+
+(define-actor <hot-tea> (<gameobj>)
+  ((cmd-drink hot-tea-cmd-drink)
+   (cmd-sip hot-tea-cmd-sip))
+  (contained-commands
+   #:allocation #:each-subclass
+   #:init-thunk (build-commands
+                 ("drink" ((direct-command cmd-drink)))
+                 ("sip" ((direct-command cmd-sip)))))
+  
+  (sips-left #:init-value 4
+             #:accessor .sips-left)
+  (name #:init-value "a cup of hot tea")
+  (take-me? #:init-value #t)
+  (goes-by #:init-value '("cup of hot tea" "cup of tea" "tea" "cup"))
+  (desc #:init-value "It's a steaming cup of hot tea.  It looks pretty good!"))
+
+(define (hot-tea-cmd-drink hot-tea message . _)
+  (define player (message-from message))
+  (define player-loc (mbody-val (<-wait player 'get-loc)))
+  (define player-name (mbody-val (<-wait player 'get-name)))
+  (<- player 'tell
+      #:text "You drink a steaming cup of hot tea all at once... hot hot hot!")
+  (<- player-loc 'tell-room
+      #:text `(,player-name
+               " drinks a steaming cup of hot tea all at once.")
+      #:exclude player)
+  (gameobj-self-destruct hot-tea))
+
+(define (hot-tea-cmd-sip hot-tea message . _)
+  (define player (message-from message))
+  (define player-loc (mbody-val (<-wait player 'get-loc)))
+  (define player-name (mbody-val (<-wait player 'get-name)))
+  (set! (.sips-left hot-tea) (- (.sips-left hot-tea) 1))
+  (<- player 'tell
+      #:text "You take a sip of your steaming hot tea.  How refined!")
+  (<- player-loc 'tell-room
+      #:text `(,player-name
+               " takes a sip of their steaming hot tea.  How refined!")
+      #:exclude player)
+  (when (= (.sips-left hot-tea) 0)
+    (<- player 'tell
+        #:text "You've finished your tea!")
+    (<- player-loc 'tell-room
+        #:text `(,player-name
+                 " finishes their tea!")
+        #:exclude player)
+    (gameobj-self-destruct hot-tea)))
+
+(define-actor <fanny-pack> (<container>)
+  ((cmd-take-from-while-wearing cmd-take-from)
+   (cmd-put-in-while-wearing cmd-put-in))
+  (contained-commands
+   #:allocation #:each-subclass
+   #:init-thunk
+   (build-commands
+    (("l" "look") ((direct-command cmd-look-at)))
+    ("take" ((prep-indir-command cmd-take-from-while-wearing
+                                 '("from" "out of"))))
+    ("put" ((prep-indir-command cmd-put-in-while-wearing
+                                '("in" "inside" "into" "on")))))))
+
 (define playroom
   (lol
    ('playroom
 (define playroom
   (lol
    ('playroom
@@ -648,7 +905,138 @@ if this room is intended for children or child-like adults.")
     #:name "a rubber duck"
     #:goes-by '("rubber duck" "duck")
     #:take-me? #t
     #:name "a rubber duck"
     #:goes-by '("rubber duck" "duck")
     #:take-me? #t
-    #:desc "It's a yellow rubber duck with a bright orange beak.")))
+    #:desc "It's a yellow rubber duck with a bright orange beak.")
+
+   ('playroom:toy-chest:tinfoil-hat
+    <tinfoil-hat> 'playroom:toy-chest
+    #:name "a tinfoil hat"
+    #:goes-by '("tinfoil hat" "hat")
+    #:take-me? #t
+    #:desc "You'd have to be a crazy person to wear this thing!")
+
+   ('playroom:toy-chest:fanny-pack
+    <fanny-pack> 'playroom:toy-chest
+    #:name "a fanny pack"
+    #:goes-by '("fanny pack" "pack")
+    #:take-me? #t
+    #:desc
+    (lambda (toy-chest whos-looking)
+      (let ((contents (gameobj-occupants toy-chest)))
+        `((p "It's a leather fanny pack, so it's both tacky and kinda cool.")
+          (p "Inside you see:"
+             ,(if (eq? contents '())
+                  " nothing!  It's empty!"
+                  `(ul ,(map (lambda (occupant)
+                               `(li ,(mbody-val
+                                      (<-wait occupant 'get-name))))
+                             (gameobj-occupants toy-chest)))))))))
+
+   ;; Things inside the toy chest
+   ('playroom:toy-chest:fanny-pack:plastic-elephant
+    <gameobj> 'playroom:toy-chest:fanny-pack
+    #:name "a plastic elephant"
+    #:goes-by '("plastic elephant" "elephant")
+    #:take-me? #t
+    #:desc "It's a tiny little plastic elephant.  Small, but heartwarming.")
+
+   ('playroom:rgb-machine
+    <rgb-machine> 'playroom
+    #:name "a Rube Goldberg machine"
+    #:goes-by '("rube goldberg machine" "machine")
+    #:rgb-items '(playroom:rgb-dominoes
+                  playroom:rgb-switch-match
+                  playroom:rgb-candle
+                  playroom:rgb-catapult
+                  playroom:rgb-water-demon
+                  playroom:rgb-quik-heater
+                  playroom:rgb-kettle)
+    #:desc "It's one of those hilarious Rube Goldberg machines.
+What could happen if you started it?")
+
+   ;; Dominoes topple
+   ('playroom:rgb-dominoes
+    <rgb-item> 'playroom
+    #:name "some dominoes"
+    #:goes-by '("dominoes" "some dominoes")
+    #:steps `("The dominoes topple down the line..."
+              1
+              "The last domino lands on a switch!"
+              1.5
+              playroom:rgb-switch-match)
+    #:reset-msg "The dominoes are placed back into position.")
+
+   ;; Which hit the switch and strike a match
+   ('playroom:rgb-switch-match
+    <rgb-item> 'playroom
+    #:name "a switch"
+    #:goes-by '("switch" "match")
+    #:steps `("The switch lights a match!"
+              ,(/ 2 3)
+              "The match lights a candle!"
+              1.5
+              playroom:rgb-candle)
+    #:reset-msg "A fresh match is installed and the switch is reset.")
+   ;; which lights a candle and burns a rope
+   ('playroom:rgb-candle
+    <rgb-item> 'playroom
+    #:name "a candle"
+    #:goes-by '("candle")
+    #:steps `("The candle burns..."
+              .3  ; oops!
+              "The candle is burning away a rope!"
+              2
+              "The rope snaps!"
+              .5
+              playroom:rgb-catapult)
+    #:reset-msg "A fresh candle is installed.")
+   ;; which catapults a rock
+   ('playroom:rgb-catapult
+    <rgb-item> 'playroom
+    #:name "a catapult"
+    #:goes-by '("catapult")
+    #:steps `("The snapped rope unleashes a catapult, which throws a rock!"
+              2
+              "The rock flies through a water demon, startling it!"
+              .5
+              playroom:rgb-water-demon
+              2
+              "The rock whacks into the quik-heater's on button!"
+              .5
+              playroom:rgb-quik-heater)
+    #:reset-msg
+    '("A fresh rope is attached to the catapult, which is pulled taught. "
+      "A fresh rock is placed on the catapult."))
+   ;; which both:
+   ;;   '- panics the water demon
+   ;;      '- which waters the kettle
+   ('playroom:rgb-water-demon
+    <rgb-item> 'playroom
+    #:name "the water demon"
+    #:triggers-as 'water-demon
+    #:goes-by '("water demon" "demon")
+    #:steps `("The water demon panics, and starts leaking water into the kettle below!"
+              3
+              "The kettle is filled!"
+              playroom:rgb-kettle)
+    #:reset-msg '("The water demon is scratched behind the ears and calms down."))
+   ;;   '- bops the quik-heater button
+   ;;      '- which heats the kettle
+   ('playroom:rgb-quik-heater
+    <rgb-item> 'playroom
+    #:name "the quik heater"
+    #:triggers-as 'quik-heater
+    #:goes-by '("quik heater" "heater")
+    #:steps `("The quik-heater heats up the kettle above it!"
+              3
+              "The kettle is heated up!"
+              playroom:rgb-kettle)
+    #:reset-msg '("The quik heater is turned off."))
+   ;; Finally, the kettle
+   ('playroom:rgb-kettle
+    <rgb-kettle> 'playroom
+    #:name "the kettle"
+    #:goes-by '("kettle")
+    #:reset-msg '("The kettle is emptied."))))
 
 
 \f
 
 
 \f
@@ -1367,8 +1755,22 @@ is a map detailing the layout of the underground structure."))
             #:to 'hive-entrance)
           (make <exit>
             #:name "east"
             #:to 'hive-entrance)
           (make <exit>
             #:name "east"
-            #:to 'federation-station)))
-
+            #:to 'federation-station)
+          (make <exit>
+            #:name "south"
+            #:traverse-check
+            (lambda (exit room whos-exiting)
+              (values #f '("Ooh, if only you could go south and check this out! "
+                           "Unfortunately this whole area is sealed off... the proprietor "
+                           "probably never got around to fixing it. "
+                           "Too bad, it would have had monsters to fight and everything!"))))
+          (make <exit>
+            #:name "southwest"
+            #:traverse-check
+            (lambda (exit room whos-exiting)
+              (values #f '("Hm, it's one of those revolving doors that only revolves in "
+                           "one direction, and it isn't this one.  You guess that while "
+                           "this doesn't appear to be an entrance, it probably is an exit."))))))
    ;; map
    ('underground-lab:map
     <readable> 'underground-lab
    ;; map
    ('underground-lab:map
     <readable> 'underground-lab
@@ -1381,7 +1783,7 @@ is a map detailing the layout of the underground structure."))
    ('underground-lab:8sync-sign
     <readable> 'underground-lab
     #:name "a sign labeled \"8sync design goals\""
    ('underground-lab:8sync-sign
     <readable> 'underground-lab
     #:name "a sign labeled \"8sync design goals\""
-    #:goes-by '("sign" "8sync design goals sign" "8sync sign")
+    #:goes-by '("sign" "8sync design goals sign" "8sync goals" "8sync design" "8sync sign")
     #:read-text 8sync-design-goals
     #:desc `((p "The sign says:")
              ,8sync-design-goals))))
     #:read-text 8sync-design-goals
     #:desc `((p "The sign says:")
              ,8sync-design-goals))))
@@ -1456,8 +1858,8 @@ as well as an exit leading to the south."))
               "and early 2016 about the need for an "
               "\"asynchronous event loop for Guile\".  The diorama "
               "is a model of the Veggie Galaxy restaurant where after "
               "and early 2016 about the need for an "
               "\"asynchronous event loop for Guile\".  The diorama "
               "is a model of the Veggie Galaxy restaurant where after "
-              "the FSF 30th anniversary party; Mark Weaver, Christopher "
-              "Allan Webber, David Thompson, and Andrew Engelbrecht chat "
+              "the FSF 30th anniversary party; Mark Weaver, Christine "
+              "Lemmer-Webber, David Thompson, and Andrew Engelbrecht chat "
               "about the need for Guile to have an answer to asynchronous "
               "programming.  A mailing list post " ; TODO: link it?
               "summarizing the discussion is released along with various "
               "about the need for Guile to have an answer to asynchronous "
               "programming.  A mailing list post " ; TODO: link it?
               "summarizing the discussion is released along with various "
@@ -1561,11 +1963,18 @@ as well as an exit leading to the south."))
    ('gift-shop
     <room> #f
     #:name "Museum Gift Shop"
    ('gift-shop
     <room> #f
     #:name "Museum Gift Shop"
-    #:desc "foo"
+    #:desc '("There are all sorts of scrolls and knicknacks laying around here, "
+             "but they all seem glued in place and instead of a person manning the shop "
+             "there's merely a cardboard cutout of a person with a \"shopkeeper\" nametag. "
+             "You can pretty well bet that someone wanted to finish this room but ran out of "
+             "time.")
     #:exits (list
              (make <exit>
                #:name "northeast"
     #:exits (list
              (make <exit>
                #:name "northeast"
-               #:to 'underground-lab)
+               #:to 'underground-lab
+               #:traverse-check
+               (lambda (exit room whos-exiting)
+                 (values #t '("The revolving door spins as you walk through it.  Whee!"))))
              (make <exit>
                #:name "north"
                #:to 'async-museum)))))
              (make <exit>
                #:name "north"
                #:to 'async-museum)))))
@@ -1859,6 +2268,66 @@ comments, and so on flowing from node to node."
 
    ))
 
 
    ))
 
+
+\f
+;;; North hall
+;;; ==========
+(define north-hall
+  (lol
+   ('north-hall
+    <room> #f
+    #:name "North Hall"
+    #:desc
+    '((p "This hallway is lined by doors to the west and the east, presumably
+to various lodgings.  Something tells you you're not able to enter those right
+now, however.  Lining the walls are some large mirrors surrounded by bouquets
+of flowers.")
+      (p "The red carpet continues all the way from Grand Hallway in the south
+but stops short of some large wooden doors to the north.  The doors look
+formidable but unlocked.  Some natural light peeking through windows to the
+north seem to hint that this may be the exit to the outdoors.  There's
+also a large sign near the doors on a wooden easel."))
+    #:exits
+    (list (make <exit>
+           #:name "south"
+           #:to 'grand-hallway)))
+   ('north-hall:sign
+    <readable> 'north-hall
+    #:name "an easel with a sign"
+    #:desc "  The easel is finely cut wood, well polished, but plain.  The sign
+is a strong contrast, with a cream colored backing and hand written letters, written
+with care and style.  You could probably read it."
+    #:read-text "The sign announces a wedding taking place... why, today!  And on
+the hotel grounds to the north!  It sounds very exciting."
+    #:goes-by '("sign"
+               "easel with a sign"
+               "easel"))
+   ('north-hall:mirrors
+    <gameobj> 'north-hall
+    #:name "a row of mirrors"
+    #:desc "You see yourself for who you really are."
+    #:invisible? #t
+    #:goes-by '("mirror" "mirrors" "row of mirrors"))
+   ('north-hall:windows
+    <gameobj> 'north-hall
+    #:name "windows"
+    #:desc "You peer out a window, but the light appears distorted, as if you were
+really peering between two worlds hastily joined together."
+    #:invisible? #t
+    #:goes-by '("window" "windows"))
+   ('north-hall:doors
+    <gameobj> 'north-hall
+    #:name "doors"
+    #:desc '((p "Along the east and west walls are doors, but they are all shut,
+and firmly so.
+Presumably people are staying in them, but it also feels as if how residence
+would work in a building as hastily put together as this was barely conceived.")
+            (p "To the north is a large set of wooden doors, oaken and beautiful.
+Although towering, they seem passable."))
+    #:invisible? #f
+    #:goes-by '("door" "doors" "room doors" "large doors"))))
+
+
 \f
 ;;; Game
 ;;; ----
 \f
 ;;; Game
 ;;; ----
@@ -1867,7 +2336,8 @@ comments, and so on flowing from node to node."
   (append lobby grand-hallway smoking-parlor
           playroom break-room computer-room underground-lab
           async-museum gift-shop hive-entrance
   (append lobby grand-hallway smoking-parlor
           playroom break-room computer-room underground-lab
           async-museum gift-shop hive-entrance
-          hive-inside federation-station))
+          hive-inside federation-station
+         north-hall))
 
 ;; TODO: Provide command line args
 (define (run-game . args)
 
 ;; TODO: Provide command line args
 (define (run-game . args)