Making a Game Server
Given what we're learned so far, we're ready to make a small process "server" that will hold our game's state. We can then send messages to it that will execute the functions we've defined. Here's a list of the commands we need to support in order to play the game:
- walk (we'll use "go" instead)
- pickup (we'll use "take" instead)
Assuming that you've already defined the variables in this function, you can create a game-state initializer like so:
(defun init-state () (make-state objects objects places (list living-room garden attic netherworld) player-location 'living-room goals goals))
There's one more thing we can do, though: take pity on the overly-curious and inclined-to-steal-frogs. Let's make sure that a player who takes too strong an interest in making new amphibian friends can amend their ways:
(defun spell-of-mercy () (timer:sleep 2000) (io:format (++ "~nFrom deep in the mists, you hear a familiar intonation ...~n" "Great relief washes over you, as you recognize the " "time-travel spell -- you're~nnot doomed!~n~n")) (timer:sleep 4000) (io:format (++ "Confident that you will never pick up the frog again, " "things get a bit fuzzy.~nYou start to lose consciousness" "as the wizard pulls you back in time. Your~nlast thought is " "that you're probably not going to remember any of this " "...~n~n")) (timer:sleep 4000) (let ((state (init-state))) (display-scene state) state))
Now we can create our state holder "server":
(defun loop-server (state) (receive (`#(look) (display-scene state) (case (state-player-location state) ('netherworld (loop-server (hope-for-mercy state))) (_ (loop-server state)))) (`#(exits) (display-exits state) (loop-server state)) (`#(go ,direction) (loop-server (walk-direction direction state))) (`#(take ,item) (loop-server (pickup-item item state))) (`#(inv) (display-inv state) (loop-server state)) (`#(weld ,subj ,obj) (loop-server (do-weld subj obj state))) (`#(dunk ,subj ,obj) (loop-server (do-dunk subj obj state))) (`#(splash ,subj ,obj) (loop-server (do-splash subj obj state))))) (defun loop-server () (loop-server (init-state)))
(defun start () (case (whereis 'game-server) ('undefined (let ((server-pid (spawn #'loop-server/0))) (register 'game-server server-pid) '#(status started))) (_ '#(status already-started)))) (defun stop (('undefined _) '#(status already-stopped)) ((pid msg) (exit pid msg) `#(status ,msg))) (defun stop () (stop (whereis 'game-server) 'game-over))
Start up your new game server!
> (start) #(status started)
Try starting (again), stopping and restarting:
> (start) #(status already-started) > (stop) #(status game-over) > (stop) #(status already-stopped) > (start) #(status started)
Next, we can cast some new SPELs for use with our server ...