#:init-thunk (build-actions
(cmd-read readable-cmd-read))))
-(define (readable-cmd-read actor message)
+(define (readable-cmd-read actor message . _)
(<- (message-from message) 'tell
- #:text (string-append (slot-ref actor 'read-text) "\n")))
+ #:text (slot-ref actor 'read-text)))
;; This one allows you to take from items that are proxied by it
<sign-in-form> 'lobby
#:name "sign-in form"
#:goes-by '("sign-in form" "form" "signin form")
- #:desc "It looks like you could sign this form and set your name.")
+ #:desc '("It looks like you could sign this form and set your name like so: "
+ (i "sign form as <my-name-here>")))
;; Object: curio cabinets
;; TODO: respond to attempts to open the curio cabinet
You can imagine yourself joining a tea party using this set, around a
nice table with some doilies, drinking some Earl Grey tea, hot. Mmmm."
#:goes-by '("tea set" "tea"))
+ ('lobby:cups
+ <cabinet-item> 'lobby
+ #:invisible? #t
+ #:name "cups from the tea set"
+ #:desc "They're chipped."
+ #:goes-by '("cups"))
('lobby:mustard-pot
<cabinet-item> 'lobby
#:invisible? #t
#:text '((p "As you attempt to pull the shield / disk platter
from the statue a shining outline appears around it... and a
completely separate, glowing copy of the disc materializes into your
-hands!")
- (p "You hear a voice whispering: "
- (i "\"Share the software... and you'll be free...\"")))))
+hands!")))
+ (<- (gameobj-loc gameobj) 'tell-room
+ #:text `(,(mbody-val (<-wait player 'get-name))
+ " pulls on the shield of the statue, and a glowing "
+ "copy of it materializes into their hands!")
+ #:exclude player)
+ (<- (gameobj-loc gameobj) 'tell-room
+ #:text
+ '(p "You hear a voice whisper: "
+ (i "\"Share the software... and you'll be free...\""))))
;;; This is the disc that gets put in the player's inventory
(define-actor <glowing-disc> (<gameobj>)
#:key direct-obj
(player (message-from message)))
(<- player 'tell
- #:text "You drop the glowing disc, and it shatters into a million
-pieces!")
+ #:text "You drop the glowing disc, and it shatters into a million pieces!")
+ (<- (mbody-val (<-wait player 'get-loc)) 'tell-room
+ #:text `(,(mbody-val (<-wait player 'get-name))
+ " drops a glowing disc, and it shatters into a million pieces!")
+ #:exclude player)
(gameobj-self-destruct gameobj))
+\f
+;;; Grand hallway
+
+(define lobby-map-text
+ "\
+ | : : |
+ .----------.----------. : & : .----------.----------.
+ | computer | |& :YOU ARE: &| smoking | *UNDER* |
+ | room + playroom + : HERE : + parlor | *CONS- |
+ | > | |& : : &| | TRUCTION*|
+ '----------'----------'-++-------++-'-------+--'----------'
+ | '-----' | | |
+ : LOBBY : '---'
+ '. .'
+ '---------'")
+
(define grand-hallway
(lol
('grand-hallway
(make <exit>
#:name "east"
#:to 'smoking-parlor)))
+ ('grand-hallway:map
+ <readable> 'grand-hallway
+ #:name "the hotel map"
+ #:desc '("This appears to be a map of the hotel. "
+ "Like the hotel itself, it seems to be "
+ "incomplete."
+ "You could read it if you want to.")
+ #:read-text `(pre ,lobby-map-text)
+ #:goes-by '("map" "hotel map"))
('grand-hallway:carpet
<gameobj> 'grand-hallway
#:name "the Grand Hallway carpet"
#:catchphrases prefect-quotes)
('smoking-parlor:no-smoking-sign
- <gameobj> 'smoking-parlor
+ <readable> 'smoking-parlor
#:invisible? #t
#:name "No Smoking Sign"
#:desc "This sign says \"No Smoking\" in big, red letters.
It has some bits of bubble gum stuck to it... yuck."
- #:goes-by '("no smoking sign" "sign"))
-
+ #:goes-by '("no smoking sign" "sign")
+ #:read-text "It says \"No Smoking\", just like you'd expect from
+a No Smoking sign.")
;; TODO: Cigar dispenser
))
;; start our main loop
(<- (actor-id clerk) 'update-loop))
-(define clerk-help-topics
- '(("changing name" .
- "Changing your name is easy! We have a clipboard here at the desk
+(define changing-name-text "Changing your name is easy!
+We have a clipboard here at the desk
where you can make yourself known to other participants in the hotel
if you sign it. Try 'sign form as <your-name>', replacing
<your-name>, obviously!")
+
+(define phd-text
+ "Ah... when I'm not here, I've got a PHD to finish.")
+
+(define clerk-help-topics
+ `(("changing name" . ,changing-name-text)
+ ("sign-in form" . ,changing-name-text)
+ ("form" . ,changing-name-text)
("common commands" .
"Here are some useful commands you might like to try: chat,
go, take, drop, say...")
The origins of the hotel are... unclear... and it has recently come
under new... 'management'. But at Hotel Bricabrac we believe these
aspects make the hotel into a fun and unique experience! Please,
-feel free to walk around and explore.")))
+feel free to walk around and explore.")
+ ("physics paper" . ,phd-text)
+ ("paper" . ,phd-text)
+ ("proprietor" . "Oh, he's that frumpy looking fellow sitting over there.")))
(define clerk-knows-about
#:allow-other-keys)
(match (slot-ref clerk 'state)
('on-duty
- (match (assoc (pk 'indir indir-obj) clerk-help-topics)
+ (match (assoc indir-obj clerk-help-topics)
((_ . info)
(<- (message-from message) 'tell
#:text
(begin
(tell-room clerk-slack-excuse-text)
;; back bto the break room
- (gameobj-set-loc! clerk (pk 'break-room (dyn-ref clerk 'break-room)))
+ (gameobj-set-loc! clerk (dyn-ref clerk 'break-room))
(tell-room clerk-return-to-slacking-text)
;; annnnnd back to slacking
(slot-set! clerk 'state 'slacking)
;; to distinguish both from the real thing.
(define-actor <hard-drive> (<gameobj>)
- ()
+ ((cmd-put-in hard-drive-insert)
+ (cmd-push-button hard-drive-push-button)
+ (get-state hard-drive-act-get-state))
+ (commands #:allocation #:each-subclass
+ #:init-thunk (build-commands
+ ("insert" ((prep-indir-command cmd-put-in
+ '("in" "inside" "into"))))
+ (("press" "push") ((prep-indir-command cmd-push-button)))))
;; the state moves from: empty -> with-disc -> loading -> ready
(state #:init-value 'empty
#:accessor .state))
+(define (hard-drive-act-get-state hard-drive message)
+ (<-reply message (.state hard-drive)))
+
(define* (hard-drive-desc hard-drive #:optional whos-looking)
`((p "The hard drive is labeled \"RL02.5\". It's a little under a meter tall.")
(p "There is a slot where a disk platter could be inserted, "
"which is pressed in and unlit")
". There is a READY indicator "
,(if (eq? (.state hard-drive) 'ready)
- "which is glowing. The machine emits a gentle whirring noise."
- "which is unlit."))))
+ "which is glowing."
+ "which is unlit.")
+ ,(if (member (.state hard-drive) '(loading ready))
+ " The machine emits a gentle whirring noise."
+ ""))))
+
+(define* (hard-drive-push-button gameobj message
+ #:key direct-obj indir-obj preposition
+ (player (message-from message)))
+ (define (tell-room text)
+ (<-wait (gameobj-loc gameobj) 'tell-room
+ #:text text))
+ (define (tell-room-excluding-player text)
+ (<-wait (gameobj-loc gameobj) 'tell-room
+ #:text text
+ #:exclude player))
+ (cond
+ ((ci-member direct-obj '("button" "load button" "load"))
+ (tell-room-excluding-player
+ `(,(mbody-val (<-wait player 'get-name))
+ " presses the button on the hard disk."))
+ (<- player 'tell
+ #:text "You press the button on the hard disk.")
+
+ (case (.state gameobj)
+ ((empty)
+ ;; I have no idea what this drive did when you didn't have a platter
+ ;; in it and pressed load, but I know there was a FAULT button.
+ (tell-room "You hear some movement inside the hard drive...")
+ (8sleep 1.5)
+ (tell-room
+ '("... but then the FAULT button blinks a couple times. "
+ "What could be missing?")))
+ ((with-disc)
+ (set! (.state gameobj) 'loading)
+ (tell-room "The hard disk begins to spin up!")
+ (8sleep 2)
+ (set! (.state gameobj) 'ready)
+ (tell-room "The READY light turns on!"))
+ ((loading ready)
+ (<- player 'tell
+ #:text '("Pressing the button does nothing right now, "
+ "but it does feel satisfying.")))))
+ (else
+ (<- player 'tell
+ #:text '("How could you think of pressing anything else "
+ "but that tantalizing button right in front of you?")))))
+
+(define* (hard-drive-insert gameobj message
+ #:key direct-obj indir-obj preposition
+ (player (message-from message)))
+ (define our-name (slot-ref gameobj 'name))
+ (define this-thing
+ (call/ec
+ (lambda (return)
+ (for-each (lambda (occupant)
+ (define goes-by (mbody-val (<-wait occupant 'goes-by)))
+ (when (ci-member direct-obj goes-by)
+ (return occupant)))
+ (mbody-val (<-wait player 'get-occupants)))
+ ;; nothing found
+ #f)))
+ (cond
+ ((not this-thing)
+ (<- player 'tell
+ #:text `("You don't seem to have any such " ,direct-obj " to put "
+ ,preposition " " ,our-name ".")))
+ ((not (mbody-val (<-wait this-thing 'get-prop 'hd-platter?)))
+ (<- player 'tell
+ #:text `("It wouldn't make sense to put "
+ ,(mbody-val (<-wait this-thing 'get-name))
+ " " ,preposition " " ,our-name ".")))
+ ((not (eq? (.state gameobj) 'empty))
+ (<- player 'tell
+ #:text "The disk drive already has a platter in it."))
+ (else
+ (set! (.state gameobj) 'with-disc)
+ (<- player 'tell
+ #:text '((p "You insert the glowing disc into the drive.")
+ (p "The LOAD button begins to glow."))))))
+
+;; The computar
+(define-actor <computer> (<gameobj>)
+ ((cmd-run-program computer-run-program)
+ (cmd-run-what (lambda (gameobj message . _)
+ (<- (message-from message) 'tell
+ #:text '("The computer is already running, and a program appears "
+ "ready to run."
+ "you mean to \"run the program on the computer\""))))
+ (cmd-help-run-not-press
+ (lambda (gameobj message . _)
+ (<- (message-from message) 'tell
+ #:text '("You don't need to press / push / flip anything. "
+ "You could " (i "run program on computer")
+ " already if you wanted to.")))))
+ (commands #:allocation #:each-subclass
+ #:init-thunk (build-commands
+ ("run" ((prep-indir-command cmd-run-program
+ '("on"))
+ (direct-command cmd-run-what)))
+ (("press" "push" "flip")
+ ((prep-indir-command cmd-help-run-not-press))))))
+
+(define* (computer-run-program gameobj message
+ #:key direct-obj indir-obj preposition
+ (player (message-from message)))
+ (define (hd-state)
+ (mbody-val (<-wait (dyn-ref gameobj 'computer-room:hard-drive) 'get-state)))
+ (define (tell-room text)
+ (<-wait (gameobj-loc gameobj) 'tell-room
+ #:text text))
+ (define (tell-room-excluding-player text)
+ (<-wait (gameobj-loc gameobj) 'tell-room
+ #:text text
+ #:exclude player))
+ (define (tell-player text)
+ (<-wait player 'tell
+ #:text text))
+ (cond
+ ((ci-member direct-obj '("program"))
+ (tell-room-excluding-player
+ `(,(mbody-val (<-wait player 'get-name))
+ " runs the program loaded on the computer..."))
+ (tell-player "You run the program on the computer...")
+
+ (cond
+ ((not (eq? (hd-state) 'ready))
+ (tell-room '("... but it errors out. "
+ "It seems to be complaining about a " (b "DISK ERROR!")
+ ". It looks like it is missing some essential software.")))
+ (else
+ (<- (dyn-ref gameobj 'computer-room:floor-panel) 'open-up))))))
+
+
+;; floor panel
+(define-actor <floor-panel> (<gameobj>)
+ ;; TODO: Add "open" verb, since obviously people will try that
+ ((open? (lambda (panel message)
+ (<-reply message (slot-ref panel 'open))))
+ (open-up floor-panel-open-up))
+ (open #:init-value #f))
+
+(define (floor-panel-open-up panel message)
+ (if (slot-ref panel 'open)
+ (<- (gameobj-loc panel) 'tell-room
+ #:text '("You hear some gears grind around the hinges of the "
+ "floor panel, but it appears to already be open."))
+ (begin
+ (slot-set! panel 'open #t)
+ (<- (gameobj-loc panel) 'tell-room
+ #:text '("You hear some gears grind, as the metal panel on "
+ "the ground opens and reveals a stairwell going down!")))))
+
+(define* (floor-panel-desc panel #:optional whos-looking)
+ `("It's a large metal panel on the floor in the middle of the room. "
+ ,(if (slot-ref panel 'open)
+ '("It's currently wide open, revealing a spiraling staircase "
+ "which descends into darkness.")
+ '("It's currently closed shut, but there are clearly hinges, and "
+ "it seems like there is a mechanism which probably opens it via "
+ "some automation. What could be down there?"))))
(define computer-room
(lol
('computer-room
<room> #f
#:name "Computer Room"
- #:desc '((p "A sizable computer cabinet covers a good portion of the left
-wall. It emits a pleasant hum which covers the room like a warm blanket.
-Connected to a computer is a large hard drive.")
- (p "On the floor is a large steel panel. It is closed, but it has
-hinges which suggest it could be opened."))
+ #:desc (lambda (gameobj whos-looking)
+ (define panel-open
+ (mbody-val (<-wait (dyn-ref gameobj 'computer-room:floor-panel)
+ 'open?)))
+ `((p "A sizable computer cabinet covers a good portion of the left
+ wall. It emits a pleasant hum which covers the room like a warm blanket.
+ Connected to a computer is a large hard drive.")
+ (p "On the floor is a large steel panel. "
+ ,(if panel-open
+ '("It is wide open, exposing a spiral staircase "
+ "which descends into darkness.")
+ '("It is closed, but it has hinges which "
+ "suggest it could be opened.")))))
#:exits
(list (make <exit>
#:name "east"
- #:to 'playroom)))
+ #:to 'playroom)
+ (make <exit>
+ #:name "down"
+ #:to 'underground-lab
+ #:traverse-check
+ (lambda (exit room whos-exiting)
+ (define panel-open
+ (mbody-val (<-wait (dyn-ref room 'computer-room:floor-panel)
+ 'open?)))
+ (if panel-open
+ (values #t "You descend the spiral staircase.")
+ (values #f '("You'd love to go down, but the only way "
+ "through is through that metal panel, "
+ "which seems closed.")))))))
('computer-room:hard-drive
<hard-drive> 'computer-room
- #:name "a hard drive"
+ #:name "the hard drive"
#:desc (wrap-apply hard-drive-desc)
- #:goes-by '("hard drive" "drive" "hard disk"))))
+ #:goes-by '("hard drive" "drive" "hard disk"))
+ ('computer-room:computer
+ <computer> 'computer-room
+ #:name "the computer"
+ #:desc '((p "It's a coat closet sized computer labeled \"PDP-11.5\". ")
+ (p "The computer is itself turned on, and it looks like it is "
+ "all set up for you to run a program on it."))
+ #:goes-by '("computer"))
+ ('computer-room:floor-panel
+ <floor-panel> 'computer-room
+ #:name "a floor panel"
+ #:desc (wrap-apply floor-panel-desc)
+ #:invisible? #t
+ #:goes-by '("floor panel" "panel"))))
+
+\f
+;;; * UNDERGROUND SECTION OF THE GAME! *
+
+\f
+;;; The lab
+
+(define underground-map-text
+ "\
+ _______ |
+ .-' @ '-. \\ ?????
+ .' '. .\\
+ | [8sync Hive] |======' '-_____
+ ', M ,'
+ '. @ .'
+ \\ @ /
+ '-__+__-'
+ '. @ .'
+ .--------------. \\ /
+ | [Guile Async | .-------+------.
+ | Museum] | | [Lab] #!#| .-------------.
+ | @| | MM | |[Federation |
+ | & ^ +##+@ || < +##| Station]|
+ | | | @ | | |
+ | & # | |*You-Are-Here*| '-------------'
+ | # ^ | #+-------+------'
+ '-------+------' # #
+ # # #
+ # # .-----------.
+ .-+----. # |# F |
+ |@?+%? +#### | ^ f## |
+ '------' | f f %|
+ |F [Mudsync |
+ | $ Swamp] |
+ '-----------'")
+
+(define 8sync-design-goals
+ '(ul (li (b "Actor based, shared nothing environment: ")
+ "Shared resources are hard to control and result in fighting
+deadlocks, etc. Escape the drudgery: only one actor controls a resource,
+and they only receive one message at a time (though they can \"juggle\"
+messages).")
+ (li (b "Live hackable: ")
+ "It's hard to plan out a concurrent system; the right structure
+is often found by evolving the system while it runs. Make it easy to
+build, shape, and change a running system, as well as observe and correct
+errors.")
+ (li (b "No callback hell: ")
+ "Just because you're calling out to some other asynchronous
+code doesn't mean you should need to chop up your program into a bunch of bits.
+Clever use of delimited continuations makes it easy.")))
+
+(define underground-lab
+ (lol
+ ('underground-lab
+ <room> #f
+ #:name "Underground laboratory"
+ #:desc '((p "This appears to be some sort of underground laboratory."
+ "There is a spiral staircase here leading upwards, where "
+ "it seems much brighter.")
+ (p "There are a number of doors leading in different directions:
+north, south, east, and west, as well as a revolving door to the southwest.
+It looks like it could be easy to get lost, but luckily there
+is a map detailing the layout of the underground structure."))
+ #:exits
+ (list (make <exit>
+ #:name "up"
+ #:to 'computer-room
+ #:traverse-check
+ (lambda (exit room whos-exiting)
+ (values #t "You climb the spiral staircase.")))
+ (make <exit>
+ #:name "west"
+ #:to 'async-museum
+ #:traverse-check
+ (lambda (exit room whos-exiting)
+ (values #t '("You head west through a fancy-looking entrance. "
+ "A security guard steps aside for you to pass through, "
+ "into the room, then stands in front of the door."))))))
+
+ ;; map
+ ('underground-lab:map
+ <readable> 'underground-lab
+ #:name "the underground map"
+ #:desc '("This appears to be a map of the surrounding area. "
+ "You could read it if you want to.")
+ #:read-text `(pre ,underground-map-text)
+ #:goes-by '("map" "underground map" "lab map"))
+
+ ('underground-lab:8sync-sign
+ <readable> 'underground-lab
+ #:name "a sign labeled \"8sync design goals\""
+ #:goes-by '("sign" "8sync design goals sign" "8sync sign")
+ #:read-text 8sync-design-goals
+ #:desc `((p "The sign says:")
+ ,8sync-design-goals))))
+
+\f
+;;; guile async museum
+
+(define async-museum
+ (list
+ (list
+ 'async-museum
+ <room> #f
+ #:name "Guile Asynchronous Museum"
+ #:desc '((p "You're in the Guile Asynchronous Museum. There is a list of exhibits
+on the wall near the entrance. Scattered around the room are the exhibits
+themselves, but it's difficult to pick them out. Maybe you should read the list
+to orient yourself.")
+ (p "There is a door to the east, watched by a security guard,
+as well as an exit leading to the south."))
+ #:exits (list
+ (make <exit>
+ #:name "south"
+ #:to 'gift-shop)
+ (make <exit>
+ #:name "east"
+ #:to 'underground-lab
+ #:traverse-check
+ (lambda (exit room whos-exiting)
+ (values #f '("The security guard stops you and tells you "
+ "that the only exit is through the gift shop."))))))
+ (list
+ 'async-museum:security-guard
+ <chatty-npc> 'async-museum
+ #:name "a security guard"
+ #:desc
+ '(p "The security guard is blocking the eastern entrance, where "
+ "you came in from.")
+ #:goes-by '("security guard" "guard" "security")
+ #:catchphrases '("It's hard standing here all day."
+ "I just want to go home."
+ "The exhibits are nice, but I've seen them all before."))
+ (let ((placard
+ `((p "Welcome to our humble museum! The exhibits are listed below. "
+ (br)
+ "To look at one, simply type: " (i "look at <exhibit-name>"))
+ (p "Available exhibits:")
+ (ul ,@(map (lambda (exhibit)
+ `(li ,exhibit))
+ '("2016 Progress"
+ "8sync and Fibers"
+ "Suspendable Ports"
+ "The Actor Model"))))))
+ (list
+ 'async-museum:list-of-exhibits
+ <readable> 'async-museum
+ #:name "list of exhibits"
+ #:desc
+ `((p "It's a list of exibits in the room. The placard says:")
+ ,@placard)
+ #:goes-by '("list of exhibits" "exhibit list" "list" "exhibits")
+ #:read-text placard))
+ (let ((desc '((p "It's a three-piece exhibit, with three little dioramas and some text "
+ "explaining what they represent. They are:")
+ (ul (li (b "Late 2015/Early 2016 talk: ")
+ "This one explains the run-up conversation from late 2015 "
+ "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 "
+ "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 "
+ "conversations around what is needed, as well as further "
+ "discussion at FOSDEM 2016.")
+ (li (b "Early implementations: ")
+ "This one shows Chris Webber's 8sync and Chris Vine's "
+ "guile-a-sync, both appearing in late 2015 and evolving "
+ "into their basic designs in early 2016. It's less a diorama "
+ "than a printout of some mailing list posts. Come on, the "
+ "curators could have done better with this one.")
+ (li (b "Suspendable ports and Fibers: ")
+ "The diorama shows Andy Wingo furiously hacking at his keyboard. "
+ "The description talks about Wingo's mailing list thread "
+ "about possibly breaking Guile compatibility for a \"ports refactor\". "
+ "Wingo releases Fibers, another asynchronous library, making use of "
+ "the new interface, and 8sync and guile-a-sync "
+ "quickly move to support suspendable ports as well. "
+ "The description also mentions that there is an exhibit entirely "
+ "devoted to suspendable ports."))
+ (p "Attached at the bottom is a post it note mentioning "
+ "https integration landing in Guile 2.2."))))
+ (list
+ 'async-museum:2016-progress-exhibit
+ <readable> 'async-museum
+ #:name "2016 Progress Exhibit"
+ #:goes-by '("2016 progress exhibit" "2016 progress" "2016 exhibit")
+ #:desc desc
+ #:read-text desc))
+ (let ((desc '((p "This exhibit is a series of charts explaining the similarities "
+ "and differences between 8sync and Fibers, two asynchronous programming "
+ "libraries for GNU Guile. It's way too wordy, but you get the general gist.")
+ (p (b "Similarities:")
+ (ul (li "Both use Guile's suspendable-ports facility")
+ (li "Both use message passing")))
+ (p (b "Differences:")
+ (ul (li "Fibers \"processes\" can read from multiple \"channels\", "
+ "but 8sync actors only read from one \"inbox\" each.")
+ (li "Different theoretical basis:"
+ (ul (li "Fibers: based on CSP (Communicating Sequential Processes), "
+ "a form of Process Calculi")
+ (li "8sync: based on the Actor Model")
+ (li "Luckily CSP and the Actor Model are \"dual\"!")))))
+ (p "Fibers is also designed by Andy Wingo, an excellent compiler hacker, "
+ "whereas 8sync is designed by Chris Webber, who built this crappy "
+ "hotel simulator."))))
+ (list
+ 'async-museum:8sync-and-fibers-exhibit
+ <readable> 'async-museum
+ #:name "8sync and Fibers Exhibit"
+ #:goes-by '("8sync and fibers exhibit" "8sync exhibit" "fibers exhibit")
+ #:desc desc
+ #:read-text desc))
+ (let ((desc '((p "This exhibit is a series of charts explaining the similarities "
+ "and differences between 8sync and Fibers, two asynchronous programming "
+ "libraries for GNU Guile. It's way too wordy, but you get the general gist.")
+ (p (b "Similarities:")
+ (ul (li "Both use Guile's suspendable-ports facility")
+ (li "Both use message passing")))
+ (p (b "Differences:")
+ (ul (li "Fibers \"processes\" can read from multiple \"channels\", "
+ "but 8sync actors only read from one \"inbox\" each.")
+ (li "Different theoretical basis:"
+ (ul (li "Fibers: based on CSP (Communicating Sequential Processes), "
+ "a form of Process Calculi")
+ (li "8sync: based on the Actor Model")
+ (li "Luckily CSP and the Actor Model are \"dual\"!")))))
+ (p "Fibers is also designed by Andy Wingo, an excellent compiler hacker, "
+ "whereas 8sync is designed by Chris Webber, who built this crappy "
+ "hotel simulator."))))
+ (list
+ 'async-museum:8sync-and-fibers-exhibit
+ <readable> 'async-museum
+ #:name "8sync and Fibers Exhibit"
+ #:goes-by '("8sync and fibers exhibit" "8sync exhibit" "fibers exhibit")
+ #:desc desc
+ #:read-text desc))
+ (list
+ 'async-museum:suspendable-ports-exhibit
+ <gameobj> 'async-museum
+ #:name "Suspendable Ports Exhibit"
+ #:goes-by '("suspendable ports exhibit" "ports exhibit"
+ "suspendable exhibit" "suspendable ports" "ports")
+ #:desc
+ '((p "Suspendable ports are a new feature in Guile 2.2, and allows code "
+ "that would normally block on IO to " (i "automatically") " suspend "
+ "to the scheduler until information is ready to be read/written!")
+ (p "Yow! You might barely need to change your existing blocking code!")
+ (p "Fibers, 8sync, and guile-a-sync now support suspendable ports.")))
+ (list
+ 'async-museum:actor-model-exhibit
+ <gameobj> 'async-museum
+ #:name "Actor Model Exhibit"
+ #:goes-by '("actor model exhibit" "actor exhibit"
+ "actor model")
+ #:desc
+ '((p "Here are some fact(oids) about the actor model!")
+ (ul (li "Originally the research goal of Scheme! (message passing anecdote here)")
+ (li "foooo"))
+ ))
+
+ ))
+
+(define gift-shop
+ (lol
+ ('gift-shop
+ <room> #f
+ #:name "Museum Gift Shop"
+ #:desc "foo"
+ #:exits (list
+ (make <exit>
+ #:name "northeast"
+ #:to 'underground-lab)
+ (make <exit>
+ #:name "north"
+ #:to 'async-museum)))))
\f
(define (game-spec)
(append lobby grand-hallway smoking-parlor
- playroom break-room computer-room))
+ playroom break-room computer-room underground-lab
+ async-museum gift-shop))
;; TODO: Provide command line args
(define (run-game . args)