readme.txt -> README.markdown
--HG--
rename : readme.txt => README.markdown
Cat's Eye Technologies
10 years ago
0 | Zzrk - Adventures in the Great Unsaturated Grammar | |
1 | ==== | |
2 | ||
3 | What is it? | |
4 | ----------- | |
5 | ||
6 | Zzrk is a toy text adventure (or, if you prefer, a toy work of interactive | |
7 | fiction) written in "pure" Zz -- assuming such a concept makes any sense. | |
8 | Zz is a dynamic meta-language designed for the APE parallel computing | |
9 | project to enable variants on languages such as FORTRAN to be quickly | |
10 | developed. As such, Zz maintains very little distinction between the | |
11 | language definition level and the language use level. For this reason, it | |
12 | might be more accurate to describe Zz as a self-modifying grammar. | |
13 | ||
14 | Since Zz is typically used to define programming languages, I thought it | |
15 | would be a nice abuse to try to use it to write an actual program (albeit | |
16 | a very language-like one.) The result is Zzrk. | |
17 | ||
18 | ||
19 | Playing the Game | |
20 | ---------------- | |
21 | ||
22 | First, you need an implementation of Zz. The only one I've found, and | |
23 | subsequently the one I've written Zzrk around, is OpenZz. It can be | |
24 | gotten from http://openzz.sourceforge.net/. | |
25 | ||
26 | Although OpenZz does have an interactive mode, it unfortunately assumes | |
27 | you're using Zz to describe a compiler. Since I assume you'll want to | |
28 | play Zzrk interactively (as opposed to typing the sequence of actions you | |
29 | want to take into a text file, piping it through Zzrk, and seeing what | |
30 | happens), here's a guide to working around some of OpenZz's drawbacks. | |
31 | ||
32 | First, you can't just specify zzrk.zz as the input to ozz. Instead, | |
33 | start OpenZz, then at the "ozz>" prompt, type | |
34 | ||
35 | /include "zzrk.zz" | |
36 | ||
37 | You can then treat the "ozz>" prompt as the prompt for the adventure | |
38 | game parser. Try the usual actions, and see what happens. Be forewarned | |
39 | that any unrecognizable command on your part -- an unknown verb, noun, or | |
40 | other part of speech -- will trigger a syntax error. And, because OpenZz | |
41 | thinks you are the input to a compiler, accumulating 10 of these errors | |
42 | will actually cause OpenZz to quit! | |
43 | ||
44 | ||
45 | The Game Itself | |
46 | --------------- | |
47 | ||
48 | The game itself is embarrassingly simplistic, but there are a few nominal | |
49 | puzzles just to demonstrate that the standard adventure game furniture can | |
50 | be concocted in Zz. Collecting treasures will get you points, and | |
51 | obtaining 50 points will win the game (that is, if you have 50 points and | |
52 | you type "score", you will get a message telling you that you have won. | |
53 | You will still need to quit OpenZz through some other manual action, such | |
54 | as typing Ctrl-D, or causing syntax errors.) | |
55 | ||
56 | ||
57 | Comments | |
58 | -------- | |
59 | ||
60 | I originally wrote zzrk.zz on November 21st, 2003. I gave it actual | |
61 | puzzles, wrote this readme, and released it under a BSD license on | |
62 | May 6, 2007. | |
63 | ||
64 | A couple of annoying things about Zz... | |
65 | ||
66 | The documentation for OpenZz doesn't mention that the /if { } construct | |
67 | has a variant that takes an else clause. And, /return does not actually | |
68 | cause an immediate return, it only assigns a value to the nonterminal | |
69 | under consideration. For these reasons, I was originally writing many of | |
70 | my tests twice (like /if a == b {} /if a != b {}). Then I noticed, in | |
71 | examining the results of /krules, that the kernel does in fact support | |
72 | else. The fact that curly braces actually denote lists means they're not | |
73 | optional in tests though, and the nesting is still pretty annoying. | |
74 | ||
75 | The other annoying thing is that there's no way to prioritize selection | |
76 | of nonterminals. For example, I feel very strongly that it ought to be | |
77 | possible to write the score_of production like this: | |
78 | ||
79 | /$num_t -> "score_of" coin { /return 5 } | |
80 | /$num_t -> "score_of" jewel { /return 10 } | |
81 | /$num_t -> "score_of" sceptre { /return 15 } | |
82 | /$num_t -> "score_of" crown { /return 20 } | |
83 | /$num_t -> "score_of" object^$ { /return 0 } | |
84 | ||
85 | On the basis that coin et al. are more specific than object^$, and should | |
86 | be selected before it. But, it's not possible to set this up, at least as | |
87 | far as I can see. Which is a pity, because this sort of "catch-all" | |
88 | mechanism would also enable much better error handling. | |
89 | ||
90 | A couple of nice things about Zz... | |
91 | ||
92 | The parser-oriented approach is, of course, very nice for an adventure | |
93 | game. It was very simple to create a parser which is in some respects | |
94 | sophisticated: it can understand "pick up the key" just as easily as | |
95 | "get key". Even nicer is that the scope rules (verbs that apply only | |
96 | to objects that are being held, are in the same room, or either) are | |
97 | implemented directly as productions in the grammar. | |
98 | ||
99 | Changing the grammar of the language you are using *on the fly* can be | |
100 | very scary, but also very powerful. Note that until you learn what the | |
101 | magic word is, you can't even use it without causing a syntax error. | |
102 | But afterward it is a full-fledged part of the parser's vocabulary. | |
103 | Note also that this is how the properties of an object are updated: | |
104 | the production which handles "e_exit square_room" is replaced by one | |
105 | that returns a different value, once the door is open. | |
106 | ||
107 | Some of the action productions are a bit clumsy because they contain | |
108 | logic that should probably be associated with the object instead. | |
109 | Putting lists of statements in a property of the object, and using | |
110 | Zz's /execute facility, would probably allow a "method-like" style | |
111 | that permits this, but I haven't played with it. | |
112 | ||
113 | Lastly, it's interesting to note that internal helper functions (not | |
114 | to mention the full complement of OpenZz builtins) are all available to | |
115 | the player during the course of the game. For example, try | |
116 | ||
117 | move player to chest | |
118 | ||
119 | and see what happens. Even better, why not try | |
120 | ||
121 | object snake "snake" "Eek!" wall wall wall wall "no" loc player | |
122 | look | |
123 | examine snake | |
124 | ||
125 | Using Zz's notion of scopes, it might be possible to protect the | |
126 | internals from being invoked like this, but considering Zzrk is just a | |
127 | toy it hardly seems worth bothering. | |
128 | ||
129 | Happy adventuring! | |
130 | ||
131 | -Chris Pressey | |
132 | May 6, 2007 | |
133 | Vancouver, BC |
0 | Zzrk - Adventures in the Great Unsaturated Grammar | |
1 | ==== | |
2 | ||
3 | What is it? | |
4 | ----------- | |
5 | ||
6 | Zzrk is a toy text adventure (or, if you prefer, a toy work of interactive | |
7 | fiction) written in "pure" Zz -- assuming such a concept makes any sense. | |
8 | Zz is a dynamic meta-language designed for the APE parallel computing | |
9 | project to enable variants on languages such as FORTRAN to be quickly | |
10 | developed. As such, Zz maintains very little distinction between the | |
11 | language definition level and the language use level. For this reason, it | |
12 | might be more accurate to describe Zz as a self-modifying grammar. | |
13 | ||
14 | Since Zz is typically used to define programming languages, I thought it | |
15 | would be a nice abuse to try to use it to write an actual program (albeit | |
16 | a very language-like one.) The result is Zzrk. | |
17 | ||
18 | ||
19 | Playing the Game | |
20 | ---------------- | |
21 | ||
22 | First, you need an implementation of Zz. The only one I've found, and | |
23 | subsequently the one I've written Zzrk around, is OpenZz. It can be | |
24 | gotten from http://openzz.sourceforge.net/. | |
25 | ||
26 | Although OpenZz does have an interactive mode, it unfortunately assumes | |
27 | you're using Zz to describe a compiler. Since I assume you'll want to | |
28 | play Zzrk interactively (as opposed to typing the sequence of actions you | |
29 | want to take into a text file, piping it through Zzrk, and seeing what | |
30 | happens), here's a guide to working around some of OpenZz's drawbacks. | |
31 | ||
32 | First, you can't just specify zzrk.zz as the input to ozz. Instead, | |
33 | start OpenZz, then at the "ozz>" prompt, type | |
34 | ||
35 | /include "zzrk.zz" | |
36 | ||
37 | You can then treat the "ozz>" prompt as the prompt for the adventure | |
38 | game parser. Try the usual actions, and see what happens. Be forewarned | |
39 | that any unrecognizable command on your part -- an unknown verb, noun, or | |
40 | other part of speech -- will trigger a syntax error. And, because OpenZz | |
41 | thinks you are the input to a compiler, accumulating 10 of these errors | |
42 | will actually cause OpenZz to quit! | |
43 | ||
44 | ||
45 | The Game Itself | |
46 | --------------- | |
47 | ||
48 | The game itself is embarrassingly simplistic, but there are a few nominal | |
49 | puzzles just to demonstrate that the standard adventure game furniture can | |
50 | be concocted in Zz. Collecting treasures will get you points, and | |
51 | obtaining 50 points will win the game (that is, if you have 50 points and | |
52 | you type "score", you will get a message telling you that you have won. | |
53 | You will still need to quit OpenZz through some other manual action, such | |
54 | as typing Ctrl-D, or causing syntax errors.) | |
55 | ||
56 | ||
57 | Comments | |
58 | -------- | |
59 | ||
60 | I originally wrote zzrk.zz on November 21st, 2003. I gave it actual | |
61 | puzzles, wrote this readme, and released it under a BSD license on | |
62 | May 6, 2007. | |
63 | ||
64 | A couple of annoying things about Zz... | |
65 | ||
66 | The documentation for OpenZz doesn't mention that the /if { } construct | |
67 | has a variant that takes an else clause. And, /return does not actually | |
68 | cause an immediate return, it only assigns a value to the nonterminal | |
69 | under consideration. For these reasons, I was originally writing many of | |
70 | my tests twice (like /if a == b {} /if a != b {}). Then I noticed, in | |
71 | examining the results of /krules, that the kernel does in fact support | |
72 | else. The fact that curly braces actually denote lists means they're not | |
73 | optional in tests though, and the nesting is still pretty annoying. | |
74 | ||
75 | The other annoying thing is that there's no way to prioritize selection | |
76 | of nonterminals. For example, I feel very strongly that it ought to be | |
77 | possible to write the score_of production like this: | |
78 | ||
79 | /$num_t -> "score_of" coin { /return 5 } | |
80 | /$num_t -> "score_of" jewel { /return 10 } | |
81 | /$num_t -> "score_of" sceptre { /return 15 } | |
82 | /$num_t -> "score_of" crown { /return 20 } | |
83 | /$num_t -> "score_of" object^$ { /return 0 } | |
84 | ||
85 | On the basis that coin et al. are more specific than object^$, and should | |
86 | be selected before it. But, it's not possible to set this up, at least as | |
87 | far as I can see. Which is a pity, because this sort of "catch-all" | |
88 | mechanism would also enable much better error handling. | |
89 | ||
90 | A couple of nice things about Zz... | |
91 | ||
92 | The parser-oriented approach is, of course, very nice for an adventure | |
93 | game. It was very simple to create a parser which is in some respects | |
94 | sophisticated: it can understand "pick up the key" just as easily as | |
95 | "get key". Even nicer is that the scope rules (verbs that apply only | |
96 | to objects that are being held, are in the same room, or either) are | |
97 | implemented directly as productions in the grammar. | |
98 | ||
99 | Changing the grammar of the language you are using *on the fly* can be | |
100 | very scary, but also very powerful. Note that until you learn what the | |
101 | magic word is, you can't even use it without causing a syntax error. | |
102 | But afterward it is a full-fledged part of the parser's vocabulary. | |
103 | Note also that this is how the properties of an object are updated: | |
104 | the production which handles "e_exit square_room" is replaced by one | |
105 | that returns a different value, once the door is open. | |
106 | ||
107 | Some of the action productions are a bit clumsy because they contain | |
108 | logic that should probably be associated with the object instead. | |
109 | Putting lists of statements in a property of the object, and using | |
110 | Zz's /execute facility, would probably allow a "method-like" style | |
111 | that permits this, but I haven't played with it. | |
112 | ||
113 | Lastly, it's interesting to note that internal helper functions (not | |
114 | to mention the full complement of OpenZz builtins) are all available to | |
115 | the player during the course of the game. For example, try | |
116 | ||
117 | move player to chest | |
118 | ||
119 | and see what happens. Even better, why not try | |
120 | ||
121 | object snake "snake" "Eek!" wall wall wall wall "no" loc player | |
122 | look | |
123 | examine snake | |
124 | ||
125 | Using Zz's notion of scopes, it might be possible to protect the | |
126 | internals from being invoked like this, but considering Zzrk is just a | |
127 | toy it hardly seems worth bothering. | |
128 | ||
129 | Happy adventuring! | |
130 | ||
131 | -Chris Pressey | |
132 | May 6, 2007 | |
133 | Vancouver, BC |