-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathBARE.ACH
496 lines (355 loc) · 15 KB
/
BARE.ACH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
# BARE.ACH
#
# A bare-bones "adventure" written in Archetype for demonstration purposes.
#
# Author: Derek T. Jones
#
#
include "standard" # must be included for normal operation
include "utility" # "extras" for types like furniture
# The first thing you've probably noticed is the # sign. The # sign,
# and anything following it up to the end of the line, is ignored
# by the CREATE program and never seen by the PERFORM program.
# It's used to leave comments for yourself or anyone else.
################################## Lexicon
# Although STANDARD.ACH includes a default lexicon, sometimes there is
# a need to define special verbs for the adventure.
# Here, we're going to define the special combination 'put...in'. Whenever
# a verb phrase and prepositional phrase are separated by an ellipsis (...)
# it means that both a subject and a direct object were found. We don't
# want to have to define this action for every object so we're defining
# it here. That way it works "backwards" even on objects that do not have
# this method defined in their lineage.
Verb null # we won't need its name
full : 'put...in'
normal : TRUE # it has a normal, or default interpretation
methods
'NORMAL' : # and here it is. Note please that we cannot
# use "self" to refer to the subject since
# "self" refers here to the Verb itself.
if main.dobj.location = main.subj then
write "But ", 'DEF' -> main.subj, " is already inside ",
'DEF' -> main.dobj, "."
else if main.dobj.open = FALSE then
write "I can't; ", 'DEF' -> main.dobj, " isn't open."
else if main.subj = main.dobj then
write "I can't put something inside itself!"
else if main.subj.stationary then
write "I can't move ", 'DEF' -> main.subj, "."
else {
main.subj.location := main.dobj; 'MOVE' -> main.subj
write "I put ", 'DEF' -> main.subj, " inside ", 'DEF' -> main.dobj, "."
}
end
################################## The Starting Room ####################
# A declaration is always a class name (e.g. "room") followed by a unique
# identifier or the word "null". You should almost always use an identifier;
# the only reason you will ever want to use "null" is if you never have
# to refer to the object declared within your program directly. One example
# of this is lexicon entries, which are usually not accessed by program
# statements.
room start_room
# Following the declaration are attributes, defined by the name of the
# attribute, a colon, and its initial value.
#
# For any object or room, you must define the "desc" attribute. This is
# its "screen name"; the way it is talked about on the screen, and, for
# objects, is used to derive the words that the player can use to refer
# to them.
desc : "starting room"
# After all attributes are finished, use the word "methods" to indicate that
# you are ready to define methods. These consist of a message, a colon,
# and a simple or compound statement.
methods
# The 'INITIAL' method is sent only once, at the very beginning.
'INITIAL' : 'START HERE' -> player # this defines the starting room
# The FIRSTDESC message is sent only the very first time that the player
# is in the room. Note the use of the write statement: just one string
# after the other is printed with no regard to margins. This is OK because
# it will wrap the words automatically.
'FIRSTDESC' : write "Welcome to the demonstration adventure! What you ",
"are seeing here is the 'FIRSTDESC' method. Although in ",
"this case there is only some writing, there is no problem ",
"with putting other executable statements here as well."
# The LONGDESC message is sent when the player first sees the room and also
# whenever they type "look" by itself at the prompt.
'LONGDESC' : write "I'm standing in a room that has the word 'START' ",
"painted on the ceiling in neon pink. The room is fairly ",
"bare otherwise."
# The "visible exits" of the room are defined here. The message is simply
# the full name of the direction; the method is the room to which it opens.
'south' : bedroom
# It is important for the method to return the name of a destination. But
# this return may be dependent on something.
'down' : if trapdoor.open then basement
end
Verb null
full : 'push'
syn : 'push down|push on'
normal : "Nothing happens."
end
object trapdoor
desc : "trapdoor"
syn : "door"
location : start_room
open : FALSE
stationary : TRUE
methods
'get' : >>It's attached to the floor.
'look' :
if open then
write "It opens downward into a yawning abyss below."
else
write "It is closed but it looks like a slight push ",
"would make it open."
'push' :
if open then
>>I already did.
else {
open := TRUE
write "I push the trapdoor and it swings downward and out, leaving ",
"a hole in the floor."
}
end
############################### The Bedroom ##########################
room bedroom
desc : "bedroom"
methods
# Unless the exit from the start_room to here was one-way, the bedroom
# has to define the exit going the other direction.
'north' : start_room
'LONGDESC' : write "I'm standing in a tastefully decorated bedroom."
end
furniture bed
# No matter what other attributes get defined for an object, ALWAYS
# define "desc" and "location". Without "location", your object is
# in limbo and will not appear anywhere in the adventure. Without
# "desc", it has no name on screen and no way for the player to refer
# to it.
desc : "brass bed"
location : bedroom
stationary : TRUE
methods
# For an object, such as this bed, the methods section contains methods
# for verb messages.
'look' : write "It's a nice four-poster brass bed. The feet have ",
"that amusing little claw-and-ball construction."
'get' : write "It's too bulky."
# The 'enter' method is already defined; you can already enter the bed
# because it's of class furniture. But for a bed, it also makes sense to
# say 'get in the bed', so we alias it to the already-defined 'enter'
# message.
#
# Note that we do not have to make a separate lexical entry for 'get in'
# because it is a compound verb formed by two other verbs already in the
# lexicon: 'get' and 'in'. Since 'in' has the synonyms 'inside' and 'into',
# if the player types 'get into the bed' or 'get inside the bed', the
# message will still come here.
'get in' : 'enter'
end
# We're going to define a class of furniture that is "openable". This
# requires the definition of the verbs "open" and "close" as well.
# Notice here that Archetype takes no notice of the end of the line
# for anything except comments (#) and quote-me's (>>).
#
# The "syn" attribute works for objects as well as lexicon entries;
# it is a list of other synonyms for the same thing. If there were
# more than one synonym, they would be separated by vertical bars.
# See the entry for 'in' in LEXICON.ACH for an example.
lex null full : 'open' end
lex null full : 'close' syn : 'shut' end
class openable based on furniture
open : FALSE
proximity : "in"
methods
# The TRANSPARENT method determines whether or not the player can access
# objects within this one without being actually inside the "openable"
# object. Note that for openable furniture, the transparency depends on
# the state of the "open" attribute.
'TRANSPARENT' : open
# Note the "writes" statement below. "writes" writes its arguments but
# does not finish the line.
'look' : {
writes "It is presently "
if open then write "open." else write "closed."
}
# Note below the 'DEF' message sent to self. All objects have a
# 'DEF' and 'INDEF' methods, meaning "definite" and "indefinite".
# 'DEF' is usually "the <object>" and 'INDEF', "a <object>" or "an <object>".
# It's better to use these because some objects may change their 'INDEF'
# or 'DEF' messages; this is more portable. Take a look at the "drawers"
# object.
'open' :
if open then
>>It's already open.
else {
open := TRUE
write "I opened ", 'DEF' -> self, "."
}
'close' :
if open then {
open := FALSE
write "I closed ", 'DEF' -> self, "."
}
else
write "It's already closed."
end
openable closet
desc : "closet"
location : bedroom
stationary : TRUE
methods
'get' : >>I don't think so.
end
class plural based on object
# This attribute is defined in the object class to be "it", but we need
# to change it for this class.
pronoun : "them"
methods
# It wouldn't make sense for plural nouns to be referred to as "a games",
# for example. They need to be "some "... when indefinite
'INDEF' : "some " & desc
end
plural games desc : "board games" location : closet end
plural books desc : "books" location : closet end
object coat desc : "winter coat" location : closet end
openable chest
desc : "small chest"
location : bedroom
methods
# Now, openable is derived from furniture, and furniture objects can
# be entered. But we don't want to be able to enter this chest. So
# we prohibit it by making the 'enter' method ABSENT. If a method
# returns this word it is just as if it were never defined. This is
# slightly different than returning UNDEFINED, which indicates that
# a method did exist and was executed but simply had an UNDEFINED return
# value.
'enter' : ABSENT
end
object necklace desc : "diamond necklace" location : chest end
openable drawers
desc : "dresser drawers"
location : bedroom
pronoun : "them"
stationary : TRUE
methods
'INDEF' : "a set of " & desc
'get' : >>Too heavy!
'enter' : ABSENT
end
############################### The Basement ########################
room basement
desc : "basement"
methods
'up' : if rope.connected then start_room
# Here, for the first time in this adventure, we need to follow a message
# with a method that is more than one statement. This is done by declaring
# a compound statment: a left curly brace, {, followed by any number of
# statements (even zero), and right curly brace, }, to finish them off.
#
# The other new thing is the >> operator. Like a comment, it is active
# all the way to the end of the line. Unlike a comment, instead of meaning
# "ignore this", it means "quote this"; it will be printed on screen
# exactly the way you wrote it. Useful for when you want text formatted
# a particular way rather than just wrapped around. Remember each >> is
# a separate statement.
'FIRSTDESC' : {
>>AAAAAAAAAAAAAAaaaaa
>> iiii
>> eeee
>> eey
>> i
>> i
>> kes
>>
>> THUMP!
>>
write "I've landed on my rear in the bottom of a dank and musty ",
"basement. The smell of mildew is overpowering. I look ",
"up but the ceiling is very high; the open trapdoor is a ",
"tiny square of light and I cannot reach it. Oh boy."
>>
}
'LONGDESC' : write "I'm standing in the bottom of a wet basement. It is ",
"rather cold and gloomy down here."
end
lex null full : 'throw' syn : 'toss|fling' end
object rope
# Note the complicated description. If we let the Archetype system
# derive usable names from this, it will get:
# coil of rope with hook on end
# of rope with hook on end
# rope with hook on end
# with hook on end
# hook on end
# on end
# end
#
# And nowhere in there is the word "rope" alone, which is probably how
# the player will use it. If the "full" attribute is defined, meaning
# "full name", then "desc" is not used to derive the name; "full" and "syn"
# are the only definitions.
desc : "coil of rope with a hook on the end"
full : "coil of rope"
syn : "coil|rope|rope coil|hook"
location : basement
connected : FALSE
methods
# Note an important technique here. Before letting the player 'get'
# the object as always, we want to check for a particular condition.
# But afterward we want to do just what was defined before. How is
# this possible since we "overwrote" the inherited 'get' message from
# object? By passing the message back to the pristine class.
'get' :
if connected then
write "It's already hooked onto the side of the trapdoor."
else
message --> object
'throw_up' : 'throw up'
'throw up' :
if connected then
write "I can't; it's hooked onto the side of the trapdoor."
else if player.location ~= basement then
write "Nothing happens."
else {
write "I throw the rope up in the air; the hook catches on the side ",
"of the trapdoor above and holds."
connected := TRUE
}
end
# A final fun surprise. Some rats which get gradually more curious
# about the player if he's fallen in the dungeon. Makes him have to
# work quickly to get out. Done by registering the object with the
# "after" event handler; every turn, after the player has made his move,
# the 'AFTER' message is sent to the object.
object rats
desc : "pack of rats"
location : basement
pronoun : "them"
curious : 0
methods
'INITIAL' : 'REGISTER' -> after
'get' : stop "I reach out towards them but that was a bad move; they ",
"come swarming over me and chew me to pieces."
'look' : write "They're staring at me with menacing beady red eyes."
# Note that the interesting part of the AFTER method is only done if
# the rats are ACCESSible to the player. For most objects 'ACCESS' -> self
# is TRUE if the player is in the same room or if the player is carrying it.
# However there are sometimes special conditions so 'ACCESS' is safer.
'AFTER' :
if 'ACCESS' -> self then {
case curious +:= 1 of {
1 : write "The rats seem to be regarding me with some interest."
2 : write "The rats are moving forward slowly, overcoming their ",
"shyness."
3 : write "The rats are advancing; the floor is full of them! ",
"They're starting to hiss and snarl!"
4 : stop "The rats leap upon me and chew me to pieces. Argh!"
}
'MENTION' -> main
}
# Note the 'MENTION' method above. That allows the sending object to be
# referred to by its pronoun, even though it was not the object last used
# as the subject of the player's sentence. This is useful when the 'AFTER'
# method may cause some message to pop out of nowhere.
end # rats