-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsample.hug
1775 lines (1570 loc) · 54.9 KB
/
sample.hug
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
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
!\---------------------------------------------------------------------------
THE VAULT OF HUGO
Hugo v2.5 Tutorial Game
by Kent Tessman (c) 1995-1999
---------------------------------------------------------------------------\!
#version 2.5
#set DEBUG ! include HugoFix library and grammar
#set VERBSTUBS ! include verb stub routines
#set USE_VEHICLES ! from OBJLIB.H
#set USE_PLURAL_OBJECTS !
#set USE_ATTACHABLES !
#set NO_AUX_MATH ! don't need advanced math routines
#switches -ls ! print statistics to SAMPLE.LST
#ifset DEBUG
#switches -d
#endif
! The following limit setting reserves 512 extra bytes of dictionary space
! so that the play can name the unnamed object. A maximum 512 bytes are
! required because the game needs to write the name, adjective, and misc
! properties of the object.
$MAXDICTEXTEND = 512
!----------------------------------------------------------------------------
! NEW GRAMMAR:
verb "kick", "punt", "boot"
* DoVague
* object DoPunt
verb "board"
* (minecar) DoEnter
verb "roll", "drive", "steer", "ride"
* DoVague
* object DoMoveinVehicle
* "to" object DoMoveinVehicle
! In the grammar definitions below, STRING refers to any section of the
! player's input enclosed in quotation marks.
verb "write", "scribble", "scrawl", "print"
* DoVague
* "on" object DoWriteOn
* "on" object "with" held DoWriteOn
* string DoWrite
* string "on" object DoWrite
* string "on" object "with" held DoWrite
* string "with" held DoWrite
verb "name", "call", "christen"
* DoVague
* (unnamedobject) DoNameWhat
* (unnamedobject) string DoName
verb "stick"
* DoVague
* (dart) DoAttachObject
* (dart) "in"/"on" (dartboard) DoAttachObject
#include "verblib.g" ! normal verb grammar
!----------------------------------------------------------------------------
#ifset PRECOMPILED_LIBRARY
#link "hugolib.hlb"
#else
#include "hugolib.h" ! standard library routines
#endif
! Normally, the library's PrintScore routine uses a MAX_SCORE/score
! formula to determine a ranking (if rankings are provided); the following
! global is used in the replaced PrintScore routine to ensure that rank is
! set by the game, not approximated by the library.
global rank
routine init
{
MAX_SCORE = 50
ranking[0] = "Amateur Adventurer"
ranking[1] = "Competent Door-Unlocker"
ranking[2] = "Bomb-Meddling Adventurer"
ranking[3] = "Master Magic Wand Finder"
ranking[4] = "The Genuine Article Sample Game Solver"
MAX_RANK = 4
counter = -1 ! 1 turn before turn 0
STATUSTYPE = 1 ! score/turns
TEXTCOLOR = DEF_FOREGROUND
BGCOLOR = DEF_BACKGROUND
SL_TEXTCOLOR = DEF_SL_FOREGROUND
SL_BGCOLOR = DEF_SL_BACKGROUND
prompt = ">"
color TEXTCOLOR, BGCOLOR
DEFAULT_FONT = PROP_ON
Font(DEFAULT_FONT)
cls
"You brace yourself, check your flashlight, and, with \
source code in hand, prepare to enter...\n"
Font(BOLD_ON)
"THE VAULT OF HUGO"
Font(BOLD_OFF)
"An Interactive Example"
print BANNER
player = you
location = outsidevault
old_location = location
move player to location ! initialize player location
FindLight(location) ! whether the player can see
DescribePlace(location) ! the appropriate description
location is visited
CalculateHolding(player) ! total size of player contents
Acquire(player, flashlight) ! give the player the flashlight
flashlight is known
Activate(key_daemon) ! set up initial daemons
InitPluralObjects
}
#ifset PRECOMPILED_LIBRARY
replace main
{
#else
routine main
{
#endif
counter = counter + 1
PrintStatusLine
run location.each_turn
runevents
RunScripts
if speaking not in location ! in case the character being spoken
speaking = 0 ! to leaves
}
player_character you "you"
{}
! flashlight
!
! The flashlight is an example of a light source. The rules for
! the FindLight routine in HUGOLIB.H check to see if any light sources
! are available (starting with the room itself, then working through
! the visible contents) before deciding if the player is able to see
! in any given location.
object flashlight "flashlight"
{
in you
nouns "flashlight", "light", "torch", "lamp"
adjective "flash"
article "your"
short_desc
{
CArt(self)
" is here, ";
if self is switchedon
"glowing brightly."
else
"turned off."
}
long_desc
{
"It's one of those disposable kinds. Built-in battery. \
$3.99 at the corner store. That sort of thing. At the
moment, it is ";
if self is switchedon
"on."
else
"off."
}
before
{
! The before property routine attempts to match the verb
! routine based on a given specifier. In the case below,
! if the verbroutine global is set to DoBurn (technically
! &DoBurn, the address of the DoBurn routine) and the
! object global is set to the flashlight object, the
! following routine is run before (in place of) the DoBurn
! routine.
object DoBurn
{Perform(&DoSwitchOn, self)}
}
after
{
! The two routines below are similar to the before routine
! above, except that they are run after the verb routine.
object DoSwitchOn
{
"A beam of serviceable light appears from your
flashlight."
self is light
FindLight(location)
if location is not visited
{DescribePlace(location)
location is visited}
}
object DoSwitchOff
{
"Your flashlight goes dark. ";
self is not light
if FindLight(location)
print newline
else
"And so does everything else."
}
}
is switchable
}
!----------------------------------------------------------------------------
! OUTSIDE THE VAULT
!----------------------------------------------------------------------------
room outsidevault "outside a vault"
{
long_desc
{"Kind of that 1930s, Bela Lugosi, graveyardy motif at
work here. It's a pretty creepy place. Directly in
front of you is the giant door to an even more giant
vault. Above the door hangs a rusty sign."}
e_to {return vaultdoor.door_to}
in_to {return vaultdoor.door_to}
cant_go
{"Vines, thorns, and bent, twisted trees bar travel in any
direction away from the vault."}
before
{
location DoDig
{
if object ~= bump
"You can't dig in that."
else
Perform(&DoSearch, bump)
}
}
}
! key_daemon
!
! This basic daemon is simply a trigger that checks every turn to see
! if 10 turns have passed. If so, it prints a brief section of prose
! before deactivating itself. (It is also deactivated if the player
! pre-emptively searches the bump in the ground.)
daemon key_daemon
{}
event key_daemon
{
if counter = 10
{
"\nAll this shuffling around outside the door has uncovered
a little bump in the ground."
event_flag = true
Deactivate(key_daemon)
}
}
scenery bump "little bump"
{
in outsidevault
nouns "bump", "ground"
adjective "little"
article "a"
long_desc
{
if key is not moved
{"It looks like there might be something there."
bump is moved}
else
{"You've already got the key. What more do
you want?"}
}
before
{
! More than one verb routine may be given as a potential
! match to a specifier in a before or after routine, as in:
object DoSearch, DoDig
{
if key is moved
"You already did. There's nothing else
to find."
else
{
bump is moved
"You find a rusty iron key!\n(Taken.)"
Acquire(player, key)
score = score + 10
Deactivate(key_daemon)
}
}
}
}
object key "rusty iron key"
{
noun "key"
adjectives "rusty", "iron"
article "a"
size 20
long_desc
{"A skeleton key. Rusty. Iron. And heavy, too. A perfect
match for the vault door, no?"}
before
{
xobject DoUnlock
{
if object = oakdoor
"The rusty key doesn't work on this door."
else
return false ! library continues as usual
}
}
}
scenery sign "rusty sign"
{
in outsidevault
noun "sign"
article "a"
adjective "rusty"
long_desc {"\"Here lies Hugo.\""}
is readable
}
! vaultdoor
!
! Notice that the found_in property specifies the rooms on either side
! of the door; OBJLIB.H does the rest. The vault door's special attribute
! is set once the player scores points for opening it.
door vaultdoor "vault door"
{
nouns "door", "doorway"
adjective "vault", "giant"
article "the"
between outsidevault, insidevault
key_object key
after
{
object DoUnlock
{
if self is not special
{
self is special
score = score + 10
rank = 1
}
return false ! library continues as usual
}
}
is not open, lockable, locked
}
scenery vault "vault"
{
in outsidevault
noun "vault"
article "the"
long_desc {"Big, imposing, and complete with rusty sign."}
door_to ! so a player can "go vault"
{return vaultdoor.door_to}
before
{
object DoEnter
{
object = vaultdoor ! change object before letting
return false ! library continue normally
}
}
}
!----------------------------------------------------------------------------
! INSIDE THE VAULT
!----------------------------------------------------------------------------
room insidevault "inside the vault"
{
long_desc
{
"Standing in the middle of this dimly lit chamber, you
realize that just maybe you should've splurged on a
more expensive flashlight. You also realize that there
are four ways you can go: a marble archway to the north,
a muddy cave opening to the east, ";
if oakdoor is not blown_open
"an oak door set in a brick frame";
else
"an empty brick frame where the oak door used to be";
" to the southeast, and west back outside where you came
from."
}
w_to {return vaultdoor.door_to}
out_to {return vaultdoor.door_to}
se_to {return oakdoor.door_to}
n_to objectroom
e_to characterroom
in_to {"You'll have to be a little more specific about which way
you want to go."}
is not light
after
{
location DoGo
! changes the way the vault is refered to from
! "a vault" to "the vault"--a stylistic thing
{
outsidevault.name = "outside the vault"
return false
}
}
vehicle_path minecar ! i.e. the mine car can travel here
}
! minecar
!
! This is an excellent example of a basic vehicle from OBJLIB.H. The
! vehicle_verbs property must mirror the valid words provided in the
! verb grammar at the start of this file. The vehicle_move property is
! checked before the vehicle is allowed to move. (This is where, for
! example, a car object would be checked to make sure that the ignition
! is turned on, or the tires aren't flat, etc.) Any room in which travel
! in the mine car is permitted must have minecar in its vehicle_path
! property.
vehicle minecar "mine car"
{
in insidevault
nouns "car", "cart"
adjectives "mine", "my", "old" ! because: synonym "mine" for "my"
! in HUGOLIB.H
article "a"
vehicle_verbs "roll", "drive", "steer", "ride"
vehicle_move
{
! Here, the mine car will not roll until the big rock is
! removed from under it. Note that the rock is not actually
! under the car, but looking under the car moves it from
! the nothing object to the room object.
if bigrock in nothing
{"Something seems to be stopping the mine car
from rolling."
return false}
}
initial_desc
{"An old mine car sits abandoned to one side."}
long_desc
{"It was probably used to haul rocks during the
excavation of the original Hugo. You could probably
get in it."}
contains_desc
{"The old mine car is loaded with";}
before
{
object DoClimb
{Perform(&DoEnter, self)}
object DoLookUnder
{
! The big rock initially begins the game in nothing;
! looking under the mine car moves it inside the
! vault.
if bigrock not in nothing
"You don't find anything else."
else
{
"You find a big rock lodged between the
wheels, which you manage to wrestle out of
the way."
move bigrock to insidevault
}
}
}
after
{
object DoEnter
{
pencil is known
return false
}
}
capacity 100
holding 0
reach minecar ! can't reach things outside the car
is container, open, static
! Because the mine car has the quiet attribute set, its contents
! (i.e. the pencil) are not immediately obvious--they are not
! listed by WhatsIn until the player specifically looks inside.
is quiet
! Also, it is mobile and therefore may be pulled by the rope.
is mobile
attach_immobile ! returns false if the car is mobile
{
if bigrock in nothing
"Something seems to be stopping the mine car
from rolling."
else: return false
}
}
object bigrock "big rock"
{
nouns "rock", "stone"
adjectives "big", "large", "huge"
article "a"
after
{
object DoGet
{"Oof. It's a struggle, but you manage to
pick it up."}
}
size 50
}
!----------------------------------------------------------------------------
! THE OBJECT ROOM
!----------------------------------------------------------------------------
room objectroom "Object Room"
{
article "the"
prep "in"
s_to insidevault
out_to insidevault
long_desc
{
"This room contains a collection of objects with different
properties, attributes, and associated routines in order
to give some idea of basic object design. In addition to
the various furnishings, you notice a dartboard hanging on
one wall."
}
vehicle_path minecar
is not light
}
! chair
!
! Try sitting in it.
object chair "wooden chair"
{
in objectroom
noun "chair"
adjective "wooden"
article "a"
reach cardtable ! i.e. only the chair and the card table
! may be reached from the chair
is enterable, static
}
! cardtable
!
! Try sitting on it. (You can't--it's not enterable.) But it can hold
! things on its surface.
object cardtable "card table"
{
in objectroom
nouns "table", "cardtable"
adjective "card"
article "a"
capacity 50
holding 0
is platform, static
}
! deckofcards and playingcard
!
! A rather unimpressive example of how to extract a single object from
! a group of similar objects. Pick a card, any card.
object deckofcards "playing cards"
{
in cardtable
noun "cards"
adjective "deck", "playing"
article "some"
initial_desc
{"A deck of playing cards has been placed appropriately
on the table."}
size 10
is plural
}
object card "playing card"
{
found_in deckofcards
noun "card" , "diamonds"
adjective "playing", "nine"
article "a"
size 5
long_desc {"It's the nine of diamonds."}
after
{
object DoGet
{
if object.found_in ~= false
{
object.found_in = false
"You deal the nine of diamonds."
object.name = "nine of diamonds"
object.article = "the"
}
else
return false
}
}
}
! goldcoins
!
! A simple demonstration of identical_class from OBJLIB.H. The coins can
! be referred to individually, by number (i.e. "two coins"), or as a
! group ("the coins").
identical_class goldcoins "shiny gold coins"
{
article "some"
nouns "coins"
adjectives "shiny", "gold"
single_noun "coin"
long_desc
"Shiny and gold: both admirable qualities in a coin."
plural_of coin1, coin2, coin3
}
object coin1 "shiny gold coin"
{
in cardtable
article "a"
noun "coin"
adjectives "shiny", "gold"
identical_to goldcoins
}
coin1 coin2 "shiny gold coin" ! copy coin1 to coin2
{
in cardtable
}
coin1 coin3 "shiny gold coin"
{
in cardtable
}
! mittens
!
! Try wearing them. Try writing when you're wearing them.
object mittens "pair of mittens"
{
in transparentbox
nouns "mitten", "mittens"
adjective "pair"
article "a"
size 10
initial_desc
{"A pair of mittens is inside the transparent box."}
is clothing
}
! box
!
! The basic box class is used by transparentbox and opaquebox. The boxes
! plural_class (from OBJLIB.H) exists only to allow the boxes to be referred
! to as a group.
plural_class boxes "boxes"
{
article "some"
noun "boxes"
single_noun "box"
plural_of transparentbox, opaquebox
}
class box "box"
{
noun "box"
article "a"
size 20
capacity 20
holding 0
long_desc
{
if self is open
"It's open."
else
"It's closed."
}
after
{
! This after routine replaces the normal library "Taken."
! response whenever a box object is the parent of the
! taken object.
parent(object) DoGet
{
print "You take "; The(object); " out of "; \
The(self); "."
}
}
plural_is boxes
is openable, not open, container
}
! transparentbox
!
! Try getting something out of it when it's closed, even if you can see
! the contents. Then try putting the flashlight in here and closing it.
box transparentbox "transparent box"
{
in objectroom
adjective "transparent", "clear"
is transparent
}
! opaquebox
!
! Now try putting the flashlight in here and closing it. The library does
! all the work of checking to see if the DoClose verb routine hides the
! light source in the room.
box opaquebox "opaque box"
{
in objectroom
adjective "opaque"
article "an"
}
box largedrum "large drum"
! the special attribute is set once it has been opened
{
in objectroom
nouns "drum", "can", "barrel"
adjectives "large", "big", "larger"
short_desc
{
"A large drum--not the musical kind--is here. ";
if warningnote is hidden
{
"Attached to it is a warning note."
warningnote is known
warningnote is already_listed
}
print newline
}
long_desc
{"It's one of those big barrels used for storing and shipping
oil, chemicals, and other hazardous materials. Hint."}
before
{
object DoGet
{"It's much too heavy to take."}
}
after
{
object DoOpen
{
! if drum hasn't been opened the first time
if self is not special
{
"Ignoring all warnings to the contrary, you
open the drum. Inside is another, smaller
drum, as well as a second warning note."
self is special
smalldrum is known
warningnote.name = "first warning note"
}
else
return false
}
}
}
plural_class notes "notes"
{
nouns "notes", "paper"
adjectives "warning", "pieces"
single_noun "note"
plural_of warningnote, secondnote
}
object warningnote "warning note"
{
in objectroom
nouns "note", "paper"
adjectives "warning", "first", "piece"
article "a"
long_desc
{"\"Do not open this drum. Whatever you do, don't open
this drum. Do not. Open. This drum.\""}
before
{
object DoGet
{self is not hidden
return false}
}
plural_is notes
is readable, hidden
}
box smalldrum "smaller drum"
! the special attribute is set once the bomb has been found
{
in largedrum
nouns "drum", "can", "barrel"
adjectives "small", "smaller", "little"
long_desc
{
"It's a smaller version of the first drum";
if secondnote is hidden
{
" (with a second warning note attached, of course)";
secondnote is known
secondnote is already_listed
}
print "."
}
before
{
object DoGet
{"Small is a relative term here. It's still too
big to pick up."}
}
after
{
object DoOpen
{
if self is not special ! if bomb hasn't been found
{
"You find a bomb. What luck."
self is special
bomb is known
Activate(bomb_fuse, 10)
score = score + 10
rank = 2
}
else
return false
}
}
}
object secondnote "second warning note"
{
in largedrum
nouns "note", "paper"
adjectives "warning", "second", "piece"
article "a"
long_desc
{"\"You listen well. But this time we mean it. Don't open
this drum.\""}
before
{
object DoGet
{
self is not hidden
return false
}
}
plural_is notes
is readable, hidden
}
object bomb "bomb"
{
in smalldrum
nouns "bomb"
article "a"
long_desc
{"Just your typical, garden-variety bomb."}
}
! bomb_fuse
!
! This fuse begins running as soon as the player opens the small drum.
! It prints a message only when it is within earshot or view of the player,
! but keeps ticking regardless.
fuse bomb_fuse
{}
event bomb_fuse
{
if bomb in player ! player is holding it
{"\nThe bomb you're holding is ticking."
event_flag = true}
elseif FindObject(bomb, location) ! bomb is visible in the room
{"\nThe bomb is ticking."
event_flag = true}
elseif Contains(location, bomb) ! bomb is otherwise in room
{"\nYou hear a ticking noise."
event_flag = true}
if not self.tick ! when self.timer = 0
{
if Contains(location, bomb) ! if in player's location
{
"\nKABOOM!\n\n\
(Right next to the bomb was not, as they say, such
a great place to be as it went off. You're dead now.)"
endflag = 2 ! when endflag is non-false, it
! immediately triggers the end of the
! game
}
else
{
"\nYou hear a muffled kaboom."
event_flag = true
if bomb in insidevault
{
oakdoor is blown_open
oakdoor is not openable
oakdoor is not hidden
score = score + 10
! The following activates the dwarf's
! script with eleven steps; the DwarfDropBall
! ensures that she drops whatever she was
! holding before going anywhere.
setscript[script(dwarf,11)] = \
&CharMove, s_obj,
&CharMove, w_obj,
&CharWait, nothing,
&CharShakeHead, oakdoor,
&CharWait, nothing,
&CharMove, n_obj,
&CharWait, nothing,
&CharShakeHead, largedrum,
&CharMove, s_obj,
&CharMove, e_obj,
&CharMove, n_obj
DwarfDropBall
}
remove bomb
Deactivate(bomb_fuse)
}
}
}
attribute written alias special ! for the pad only
array writing[65] ! up to 64 characters of writing
! pad
!
! Try: write "something" on paper.
object pad "pad of paper"
{
in cardtable
article "a"
nouns "paper"
adjective "pad", "regular", "writing"