X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=worlds%2Fbricabrac.scm;h=6bdadca3e6c6af9a39b898f74e354f314767452b;hb=refs%2Fheads%2F8sync-fibers;hp=a21829f2886042b06349afd143e4eb98ceee93d8;hpb=bd2d3b63f0e8df23cd28aec4a9b11acfc52c7770;p=mudsync.git diff --git a/worlds/bricabrac.scm b/worlds/bricabrac.scm index a21829f..6bdadca 100644 --- a/worlds/bricabrac.scm +++ b/worlds/bricabrac.scm @@ -1,5 +1,5 @@ ;;; Mudsync --- Live hackable MUD -;;; Copyright © 2016 Christopher Allan Webber +;;; Copyright © 2016, 2017 Christopher Allan Webber ;;; ;;; This file is part of Mudsync. ;;; @@ -21,6 +21,7 @@ (use-modules (mudsync) (mudsync container) (8sync) + (8sync daydream) (oop goops) (ice-9 control) (ice-9 format) @@ -61,6 +62,14 @@ #:text (slot-ref actor 'read-text))) +;; This one is just where reading is the same thing as looking +;; at the description +(define-class () + (commands + #:allocation #:each-subclass + #:init-thunk (build-commands + ("read" ((direct-command cmd-look-at)))))) + ;; This one allows you to take from items that are proxied by it (define-actor () ((cmd-take-from take-from-proxy)) @@ -74,8 +83,7 @@ (for-each (lambda (obj-sym) (define obj-id (dyn-ref gameobj obj-sym)) - (define goes-by - (mbody-val (<-wait obj-id 'goes-by))) + (define goes-by (<-wait obj-id 'goes-by)) (when (ci-member direct-obj goes-by) (<- obj-id 'cmd-take #:direct-obj direct-obj #:player player) (escape #f))) @@ -154,8 +162,7 @@ or 'skribe'? Now *that's* composition!")) (define* (sign-cmd-sign-in actor message #:key direct-obj indir-obj preposition) - (define old-name - (mbody-val (<-wait (message-from message) 'get-name))) + (define old-name (<-wait (message-from message) 'get-name)) (define name indir-obj) (if (valid-name? indir-obj) (begin @@ -185,8 +192,7 @@ character.\n"))) ;; and find out their name. We'll call *their* get-name message ;; handler... meanwhile, this procedure suspends until we get ;; their response. - (define who-rang - (mbody-val (<-wait (message-from message) 'get-name))) + (define who-rang (<-wait (message-from message) 'get-name)) ;; Now we'll invoke the "tell" message handler on the player ;; who rang us, displaying this text on their screen. @@ -438,10 +444,10 @@ from the statue a shining outline appears around it... and a completely separate, glowing copy of the disc materializes into your 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) + #:text `(,(<-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: " @@ -469,8 +475,8 @@ labeled \"RL02.5\".") (player (message-from message))) (<- player 'tell #: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)) + (<- (<-wait player 'get-loc) 'tell-room + #:text `(,(<-wait player 'get-name) " drops a glowing disc, and it shatters into a million pieces!") #:exclude player) (gameobj-self-destruct gameobj)) @@ -589,6 +595,243 @@ platter! It has \"RL02.5\" written on it. It looks kind of loose." ;;; Playroom ;;; -------- +(define-actor () + ((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 `(,(<-wait player 'get-name) + " runs the rube goldberg machine.") + #:exclude player) + (daydream 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 `(,(<-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.")) + (daydream (/ 1 2)) + (for-each + (lambda (rgb-item) + (<- (dyn-ref rgb-machine rgb-item) 'reset) + (daydream (/ 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 () + ((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) + (daydream 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 () + ((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!")) + (daydream .25) + (set! (.state rgb-item) 'ran) + ;; insert a cup of hot tea in the room + (create-gameobj (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 () + ((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 () + ((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 (<-wait player 'get-loc)) + (define player-name (<-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 (<-wait player 'get-loc)) + (define player-name (<-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 () + ((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 @@ -628,8 +871,7 @@ if this room is intended for children or child-like adults.") ,(if (eq? contents '()) " nothing! It's empty!" `(ul ,(map (lambda (occupant) - `(li ,(mbody-val - (<-wait occupant 'get-name)))) + `(li ,(<-wait occupant 'get-name))) (gameobj-occupants toy-chest)))))))) #:take-from-me? #t #:put-in-me? #t) @@ -640,7 +882,137 @@ if this room is intended for children or child-like adults.") #: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 + '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 + '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 ,(<-wait occupant 'get-name))) + (gameobj-occupants toy-chest))))))))) + + ;; Things inside the toy chest + ('playroom:toy-chest:fanny-pack:plastic-elephant + '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 + '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 + '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 + '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 + 'playroom + #:name "a candle" + #:goes-by '("candle") + #:steps `("The candle burns..." + (/ 2 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 + '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 + '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 + '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 + 'playroom + #:name "the kettle" + #:goes-by '("kettle") + #:reset-msg '("The kettle is emptied.")))) @@ -672,7 +1044,7 @@ if this room is intended for children or child-like adults.") (define* (furniture-cmd-sit actor message #:key direct-obj) (define player-name - (mbody-val (<-wait (message-from message) 'get-name))) + (<-wait (message-from message) 'get-name)) (<- (message-from message) 'tell #:text (format #f "You ~a ~a.\n" (slot-ref actor 'sit-phrase) @@ -897,7 +1269,7 @@ You can ask me about the following: (define* (clerk-cmd-dismiss clerk message . _) (define player-name - (mbody-val (<-wait (message-from message) 'get-name))) + (<-wait (message-from message) 'get-name)) (match (slot-ref clerk 'state) ('on-duty (<- (gameobj-loc clerk) 'tell-room @@ -959,7 +1331,7 @@ if you need further help.") (match (slot-ref clerk 'state) ('slacking (tell-room (random-choice clerk-slacking-texts)) - (8sleep (+ (random 20) 15)) + (daydream (+ (random 20) 15)) (loop-if-not-destructed)) ('on-duty (if (> (slot-ref clerk 'patience) 0) @@ -968,7 +1340,7 @@ if you need further help.") (tell-room (random-choice clerk-working-impatience-texts)) (slot-set! clerk 'patience (- (slot-ref clerk 'patience) (+ (random 2) 1))) - (8sleep (+ (random 60) 40)) + (daydream (+ (random 60) 40)) (loop-if-not-destructed)) ;; Back to slacking (begin @@ -978,7 +1350,7 @@ if you need further help.") (tell-room clerk-return-to-slacking-text) ;; annnnnd back to slacking (slot-set! clerk 'state 'slacking) - (8sleep (+ (random 30) 15)) + (daydream (+ (random 30) 15)) (loop-if-not-destructed)))))) @@ -1046,7 +1418,7 @@ the paint, but the wires themselves seem to be unusually sturdy." #:accessor .state)) (define (hard-drive-act-get-state hard-drive message) - (<-reply message (.state hard-drive))) + (.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.") @@ -1079,7 +1451,7 @@ the paint, but the wires themselves seem to be unusually sturdy." (cond ((ci-member direct-obj '("button" "load button" "load")) (tell-room-excluding-player - `(,(mbody-val (<-wait player 'get-name)) + `(,(<-wait player 'get-name) " presses the button on the hard disk.")) (<- player 'tell #:text "You press the button on the hard disk.") @@ -1089,14 +1461,14 @@ the paint, but the wires themselves seem to be unusually sturdy." ;; 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) + (daydream 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) + (daydream 2) (set! (.state gameobj) 'ready) (tell-room "The READY light turns on!")) ((loading ready) @@ -1116,10 +1488,10 @@ the paint, but the wires themselves seem to be unusually sturdy." (call/ec (lambda (return) (for-each (lambda (occupant) - (define goes-by (mbody-val (<-wait occupant 'goes-by))) + (define goes-by (<-wait occupant 'goes-by)) (when (ci-member direct-obj goes-by) (return occupant))) - (mbody-val (<-wait player 'get-occupants))) + (<-wait player 'get-occupants)) ;; nothing found #f))) (cond @@ -1127,10 +1499,10 @@ the paint, but the wires themselves seem to be unusually sturdy." (<- 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?))) + ((not (<-wait this-thing 'get-prop 'hd-platter?)) (<- player 'tell #:text `("It wouldn't make sense to put " - ,(mbody-val (<-wait this-thing 'get-name)) + ,(<-wait this-thing 'get-name) " " ,preposition " " ,our-name "."))) ((not (eq? (.state gameobj) 'empty)) (<- player 'tell @@ -1167,7 +1539,7 @@ the paint, but the wires themselves seem to be unusually sturdy." #: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))) + (<-wait (dyn-ref gameobj 'computer-room:hard-drive) 'get-state)) (define (tell-room text) (<-wait (gameobj-loc gameobj) 'tell-room #:text text)) @@ -1181,7 +1553,7 @@ the paint, but the wires themselves seem to be unusually sturdy." (cond ((ci-member direct-obj '("program")) (tell-room-excluding-player - `(,(mbody-val (<-wait player 'get-name)) + `(,(<-wait player 'get-name) " runs the program loaded on the computer...")) (tell-player "You run the program on the computer...") @@ -1198,7 +1570,7 @@ the paint, but the wires themselves seem to be unusually sturdy." (define-actor () ;; TODO: Add "open" verb, since obviously people will try that ((open? (lambda (panel message) - (<-reply message (slot-ref panel 'open)))) + (slot-ref panel 'open))) (open-up floor-panel-open-up)) (open #:init-value #f)) @@ -1229,8 +1601,8 @@ the paint, but the wires themselves seem to be unusually sturdy." #:name "Computer Room" #:desc (lambda (gameobj whos-looking) (define panel-open - (mbody-val (<-wait (dyn-ref gameobj 'computer-room:floor-panel) - 'open?))) + (<-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.") @@ -1250,8 +1622,8 @@ the paint, but the wires themselves seem to be unusually sturdy." #:traverse-check (lambda (exit room whos-exiting) (define panel-open - (mbody-val (<-wait (dyn-ref room 'computer-room:floor-panel) - 'open?))) + (<-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 " @@ -1290,7 +1662,7 @@ the paint, but the wires themselves seem to be unusually sturdy." | [8sync Hive] |======' '-_____ ', M ,' '. @ .' - \\ @ / + \\ @ / '-__+__-' '. @ .' .--------------. \\ / @@ -1356,8 +1728,25 @@ is a map detailing the layout of the underground structure.")) "into the room, then stands in front of the door.")))) (make #:name "north" - #:to 'hive-entrance))) - + #:to 'hive-entrance) + (make + #:name "east" + #:to 'federation-station) + (make + #: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 + #: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 'underground-lab @@ -1370,7 +1759,7 @@ is a map detailing the layout of the underground structure.")) ('underground-lab:8sync-sign '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)))) @@ -1432,98 +1821,92 @@ as well as an exit leading to the south.")) ,@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 - '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 - '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 - '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:2016-progress-exhibit + 'async-museum + #:name "2016 Progress Exhibit" + #:goes-by '("2016 progress exhibit" "2016 progress" "2016 exhibit") + #: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:8sync-and-fibers-exhibit + 'async-museum + #:name "8sync and Fibers Exhibit" + #:goes-by '("8sync and fibers exhibit" "8sync exhibit" "fibers exhibit") + #: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 + 'async-museum + #:name "8sync and Fibers Exhibit" + #:goes-by '("8sync and fibers exhibit" "8sync exhibit" "fibers exhibit") + #: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:suspendable-ports-exhibit - 'async-museum + 'async-museum #:name "Suspendable Ports Exhibit" #:goes-by '("suspendable ports exhibit" "ports exhibit" "suspendable exhibit" "suspendable ports" "ports") @@ -1535,7 +1918,7 @@ as well as an exit leading to the south.")) (p "Fibers, 8sync, and guile-a-sync now support suspendable ports."))) (list 'async-museum:actor-model-exhibit - 'async-museum + 'async-museum #:name "Actor Model Exhibit" #:goes-by '("actor model exhibit" "actor exhibit" "actor model") @@ -1556,11 +1939,18 @@ as well as an exit leading to the south.")) ('gift-shop #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 #: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 #:name "north" #:to 'async-museum))))) @@ -1644,6 +2034,216 @@ that thing soon.")))) ;;; Inside the hive +(define-actor () + ((cmd-read meta-message-read))) + +(define (meta-message-read gameobj message . _) + (define meta-message-text + (with-output-to-string + (lambda () + (pprint-message message)))) + (<- (message-from message) 'tell + #:text `((p (i "Through a bizarre error in spacetime, the message " + "prints itself out:")) + (p (pre ,meta-message-text))))) + + +;;; Inside the Hive + +(define hive-inside + (lol + ('hive-inside + #f + #:name "Inside the 8sync Hive" + #:desc + '((p "You're inside the 8sync Hive. Wow, from in here it's obvious just how " + (i "goopy") " everything is. Is that sanitary?") + (p "In the center of the room is a large, tentacled monster who is sorting, +consuming, and routing messages. It is sitting in a wrap-around desk labeled +\"Hive Actor: The Real Thing (TM)\".") + (p "There's a stray message floating just above the ground, stuck outside of +time.") + (p "A door to the south exits from the Hive.")) + #:exits + (list (make + #:name "south" + #:to 'hive-entrance))) + ;; hive actor + ;; TODO: Occasionally "fret" some noises, similar to the Clerk. + ('hive-inside:hive-actor + 'hive-inside + #:name "the Hive Actor" + #:desc + '((p "It's a giant tentacled monster, somehow integrated with the core of +this building. A chute is dropping messages into a bin on its desk which the +Hive Actor is checking the \"to\" line of, then ingesting. Whenever the Hive +Actor injests a messsage a pulse of light flows along a tentacle which leaves +the room... presumably connecting to one of those actors milling about.") + (p "Amusingly, the Hive has an \"umbellical cord\" type tentacle too, but +it seems to simply attach to itself.") + (p "You get the sense that the Hive Actor, despite being at the +center of everything, is kind of lonely and would love to chat if you +could spare a moment.")) + #:goes-by '("hive" "hive actor") + #:chat-format (lambda (npc catchphrase) + `("The tentacle monster bellows, \"" ,catchphrase "\"")) + #:catchphrases + '("It's not MY fault everything's so GOOPY around here. Blame the +PROPRIETOR." + "CAN'T you SEE that I'm BUSY??? SO MANY MESSAGES TO SHUFFLE. +No wait... DON'T GO! I don't get many VISITORS." + "I hear the FIBERS system has a nice WORK STEALING system, but the +PROPRIETOR is not convinced that our DESIGN won't CORRUPT ACTOR STATE. +That and the ACTORS threatened to STRIKE when it CAME UP LAST." + "WHO WATCHES THE ACTORS? I watch them, and I empower them. +BUT WHO WATCHES OR EMPOWERS ME??? Well, that'd be the scheduler." + "The scheduler is NO GOOD! The proprietory said he'd FIX IT, +but the LAST TIME I ASKED how things were GOING, he said he DIDN'T HAVE +TIME. If you DON'T HAVE TIME to fix the THING THAT POWERS THE TIME, +something is TERRIBLY WRONG." + "There's ANOTHER HIVE somewhere out there. I HAVEN'T SEEN IT +personally, because I CAN'T MOVE, but we have an AMBASSADOR which forwards +MESSAGES to the OTHER HIVE.")) + ;; chute + ('hive-inside:chute + 'hive-inside + #:name "a chute" + #:goes-by '("chute") + #:desc "Messages are being dropped onto the desk via this chute." + #:invisible? #t) + ;; meta-message + ('hive-inside:meta-message + 'hive-inside + #:name "a stray message" + #:goes-by '("meta message" "meta-message" "metamessage" "message" "stray message") + #:desc '((p "Something strange has happened to the fabric and space and time +around this message. It is floating right above the floor. It's clearly +rubbage that hadn't been delivered, but for whatever reason it was never +garbage collected, perhaps because it's impossible to do.") + (p "You get the sense that if you tried to read the message +that you would somehow read the message of the message that instructed to +read the message itself, which would be both confusing and intriguing."))) + ;; desk + ('hive-inside:desk + 'hive-inside + #:name "the Hive Actor's desk" + #:desc "The desk surrounds the Hive Actor on all sides, and honestly, it's a little +bit hard to tell when the desk ends and the Hive Actor begins." + #:invisible? #t + #:goes-by '("Hive Actor's desk" "hive desk" "desk")))) + + +;;; Federation Station +(define federation-station + (lol + ('federation-station + #f + #:name "Federation Station" + #:desc + '((p "This room has an unusual structure. It's almost as if a starscape +covered the walls and ceiling, but upon closer inspection you realize that +these are all brightly glowing nodes with lines drawn between them. They +seem decentralized, and yet seem to be sharing information as if all one +network.") + ;; @@: Maybe add the cork message board here? + (p "To the west is a door leading back to the underground laboratory.")) + #:exits + (list (make + #:name "west" + #:to 'underground-lab))) + ;; nodes + ('federation-station:nodes + 'federation-station + #:name "some nodes" + #:desc "Each node seems to be producing its own information, but publishing +updates to subscribing nodes on the graph. You see various posts of notes, videos, +comments, and so on flowing from node to node." + #:invisible? #t + #:goes-by '("nodes" "node" "some nodes")) + ;; network + ;; activitypub poster + ('federation-station:activitypub-poster + 'federation-station + #:name "an ActivityPub poster" + #:goes-by '("activitypub poster" "activitypub" "poster") + #:desc + '((p (a "https://www.w3.org/TR/activitypub/" + "ActivityPub") + " is a federation standard being developed under the " + (a "https://www.w3.org/wiki/Socialwg/" + "w3C Social Working Group") + ", and doubles as a general client-to-server API. " + "It follows a few simple core ideas:") + (ul (li "Uses " + (a "https://www.w3.org/TR/activitystreams-core/" + "ActivityStreams") + " for its serialization format: easy to read, e json(-ld) syntax " + "with an extensible vocabulary covering the majority of " + "social networking interations.") + (li "Email-like addressing: list of recipients as " + (b "to") ", " (b "cc") ", " (b "bcc") " fields.") + (li "Every user has URLs for their outbox and inbox:" + (ul (li (b "inbox: ") + "Servers POST messages to addressed recipients' inboxes " + "to federate out content. " + "Also doubles as endpoint for a client to read most " + "recently received messages via GET.") + (li (b "outbox: ") + "Clients can POST to user's outbox to send a message to others. " + "(Similar to sending an email via your MTA.) " + "Doubles as endpoint others can read from to the " + "extent authorized; for example publicly available posts.")) + "All the federation bits happen by servers posting to users' inboxes.")))) + ;; An ActivityStreams message + + ;; conspiracy chart + ('federation-station:conspiracy-chart + 'federation-station + #:name "a conspiracy chart" + #:goes-by '("conspiracy chart" "chart") + #:desc + '((p (i "\"IT'S ALL RELATED!\"") " shouts the over-exuberant conspiracy " + "chart. " + (i "\"ActivityPub? Federation? The actor model? Scheme? Text adventures? " + "MUDS???? What do these have in common? Merely... EVERYTHING!\"")) + (p "There are circles and lines drawn between all the items in red marker, " + "with scrawled notes annotating the theoretical relationships. Is the " + "author of this poster mad, or onto something? Perhaps a bit of both. " + "There's a lot written here, but here are some of the highlights:") + (p + (ul + (li (b "Scheme") " " + (a "http://cs.au.dk/~hosc/local/HOSC-11-4-pp399-404.pdf" + "was originally started ") + " to explore the " (b "actor model") + ". (It became more focused around studying the " (b "lambda calculus") + " very quickly, while also uncovering relationships between the two systems.)") + ;; Subject Predicate Object + (li "The " (a "https://www.w3.org/TR/activitypub/" + (b "ActivityPub")) + " protocol for " (b "federation") + " uses the " (b "ActivityStreams") " format for serialization. " + (b "Text adventures") " and " (b "MUDS") + " follow a similar structure to break down the commands of players.") + (li (b "Federation") " and the " (b "actor model") " both are related to " + "highly concurrent systems and both use message passing to communicate " + "between nodes.") + (li "Zork, the first major text adventure, used the " (b "MUDDLE") " " + "language as the basis for the Zork Interactive Language. MUDDLE " + "is very " (b "Scheme") "-like and in fact was one of Scheme's predecessors. " + "And of course singleplayer text adventures like Zork were the " + "predecessors to MUDs.") + (li "In the 1990s, before the Web became big, " (b "MUDs") + " were an active topic of research, and there was strong interest " + (a "http://www.saraswat.org/desiderata.html" + "in building decentralized MUDs") + " similar to what is being " + "worked on for " (b "federation") ". "))))) + + ;; goblin + + )) + ;;; Game ;;; ---- @@ -1651,7 +2251,8 @@ that thing soon.")))) (define (game-spec) (append lobby grand-hallway smoking-parlor playroom break-room computer-room underground-lab - async-museum gift-shop hive-entrance)) + async-museum gift-shop hive-entrance + hive-inside federation-station)) ;; TODO: Provide command line args (define (run-game . args)