New Upstream Release - open-adventure

Ready changes

Summary

Merged new upstream version: 1.16 (was: 1.12).

Diff

diff --git a/.gitignore b/.gitignore
index ddb549b..7aa1928 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+# SPDX-FileCopyrightText: Eric S. Raymond
+# SPDX-License-Identifier: BSD-2-Clause
 advent
 *.gcda
 *.gcno
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0d0ab9d..6b6bd6d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,3 +1,5 @@
+# SPDX-FileCopyrightText: Eric S. Raymond
+# SPDX-License-Identifier: BSD-2-Clause
 stages:
   - ci-build
   - build
diff --git a/.shipper b/.shipper
index a34d7d6..d3ed58d 100644
--- a/.shipper
+++ b/.shipper
@@ -1,3 +1,5 @@
+#SPDX-FileCopyrightText: Eric S. Raymond
+#SPDX-License-Identifier: BSD-2-Clause
 extralines="""
 <p>There is a <a href="http://esr.gitlab.io/open-adventure/coverage/">code coverage analysis</a> and a <a href="http://esr.gitlab.io/open-adventure/coverage/adventure.yaml.html">symbol coverage analysis</p>
 """
diff --git a/COPYING b/COPYING
index c4da3e1..b1de571 100644
--- a/COPYING
+++ b/COPYING
@@ -1,7 +1,4 @@
-			BSD LICENSE
-
-Copyright (c) 1977, 2005 by Will Crowther and Don Woods
-Copyright (c) 2017 by Eric S. Raymond
+		BSD 2-Clause LICENSE
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
diff --git a/Dockerfile.ci b/Dockerfile.ci
index 535ed65..e67cd1f 100644
--- a/Dockerfile.ci
+++ b/Dockerfile.ci
@@ -1,5 +1,7 @@
 # This image is built by the Gitlab CI pipeline to be used in subsequent
 # pipeline steps.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 
 FROM ubuntu
 
diff --git a/INSTALL.adoc b/INSTALL.adoc
index a51b8ac..f61783c 100644
--- a/INSTALL.adoc
+++ b/INSTALL.adoc
@@ -1,4 +1,6 @@
 = Installing Open Adventure =
+// SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+// SPDX-License-Identifier: CC-BY-4.0
 
 Installation now requires Python3 due to a security issue
 with the YAML library.
diff --git a/Makefile b/Makefile
index 59f7e4e..8a09496 100644
--- a/Makefile
+++ b/Makefile
@@ -1,14 +1,18 @@
 # Makefile for the open-source release of adventure 2.5
 
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+
 # To build with save/resume disabled, pass CFLAGS="-DADVENT_NOSAVE"
+# To build with auto-save/resume enabled, pass CFLAGS="-DADVENT_AUTOSAVE"
 
-VERS=$(shell sed -n <NEWS '/^[0-9]/s/:.*//p' | head -1)
+VERS=$(shell sed -n <NEWS.adoc '/^[0-9]/s/:.*//p' | head -1)
 
 .PHONY: debug indent release refresh dist linty html clean
 .PHONY: check coverage
 
 CC?=gcc
-CCFLAGS+=-std=c99 -D_DEFAULT_SOURCE -DVERSION=\"$(VERS)\" -O2 -D_FORTIFY_SOURCE=2 -fstack-protector-all $(CFLAGS) -g
+CCFLAGS+=-std=c99 -D_DEFAULT_SOURCE -DVERSION=\"$(VERS)\" -O2 -D_FORTIFY_SOURCE=2 -fstack-protector-all $(CFLAGS) -g $(EXTRA)
 LIBS=$(shell pkg-config --libs libedit)
 INC+=$(shell pkg-config --cflags libedit)
 
@@ -64,10 +68,12 @@ cheat: $(CHEAT_OBJS) dungeon.o
 check: advent cheat
 	cd tests; $(MAKE) --quiet
 
+# Requires gcov, lcov, libasan6, and libubsan1
+# The last two are Ubuntu names, might vary onb other distributions.
 # After this, run your browser on coverage/open-adventure/index.html
 # to see coverage results. Browse coverage/adventure.yaml.html
 # to see symbol coverage over the YAML file.
-coverage: debug
+coverage: clean debug
 	cd tests; $(MAKE) coverage --quiet
 
 .SUFFIXES: .adoc .html .6
@@ -83,7 +89,7 @@ coverage: debug
 html: advent.html history.html hints.html
 
 # README.adoc exists because that filename is magic on GitLab.
-DOCS=COPYING NEWS README.adoc advent.adoc history.adoc notes.adoc hints.adoc advent.6 INSTALL.adoc
+DOCS=COPYING NEWS.adoc README.adoc advent.adoc history.adoc notes.adoc hints.adoc advent.6 INSTALL.adoc
 TESTFILES=tests/*.log tests/*.chk tests/README tests/decheck tests/Makefile
 
 # Can't use GNU tar's --transform, needs to build under Alpine Linux.
@@ -128,6 +134,11 @@ linty: CCFLAGS += -Winit-self
 linty: CCFLAGS += -Wpointer-arith
 linty: advent cheat
 
+# These seem to be more modeern options for enabling coverage testing.
+# Documenting them here in case a future version bump disables --coverage.
+#debug: CCFLAGS += -ftest-coverage
+#debug: CCFLAGS += -fprofile-arcs
+
 debug: CCFLAGS += -O0
 debug: CCFLAGS += --coverage
 debug: CCFLAGS += -ggdb
@@ -140,6 +151,5 @@ CSUPPRESSIONS = --suppress=missingIncludeSystem --suppress=invalidscanf
 cppcheck:
 	cppcheck -I. --template gcc --enable=all $(CSUPPRESSIONS) *.[ch]
 
-PYSUPPRESSIONS = line-too-long,invalid-name,missing-function-docstring,too-many-lines,too-many-branches,global-statement,multiple-imports,too-many-locals,too-many-statements,too-many-nested-blocks,no-else-return,raise-missing-from,redefined-outer-name,consider-using-in,dict-iter-missing-items
 pylint:
-	@pylint --score=n --disable=$(PYSUPPRESSIONS) *.py */*.py
+	@pylint --score=n *.py */*.py
diff --git a/NEWS b/NEWS.adoc
similarity index 72%
rename from NEWS
rename to NEWS.adoc
index 78f302c..54774fe 100644
--- a/NEWS
+++ b/NEWS.adoc
@@ -1,7 +1,25 @@
 = Open Adventure project news =
+// SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+// SPDX-License-Identifier: CC-BY-4.0
+
+1.16: 2023-04-15::
+  Savefiles now have an identifying magic cookie at the front.
+  Resume detects if a save has incompatible endianness.
+
+1.15: 2023-04-03::
+  Commands in magic-word sequence now interrupt it, as in original.
+  Bug fix for bird not starting caged in endgame.
+
+1.14: 2023-03-09::
+  Added -a option for BBS door systems.
+  -o reverts to the old message on some failed magic words. 
+  Typo fixes and documentation polishing.
+
+1.13: 2023-02-28::
+  Fixed slightly buggy emission of end-of-game messages on a win.
 
 1.12: 2023-02-06::
-  The bug and todo list has been cleared.
+  The bug and todo list has been cleared; project declared finished.
   Correctness has been systematically tested against the 1995 code.
   Typo fixes and documentation polishing.
 
@@ -11,7 +29,7 @@
 
 1.10: 2022-04-06::
   Fixed a bug that manifested after two "fly rug" commands - third one fails.
-  Fix some giltches in processing fee fie foe foo.
+  Fix some glitches in processing fee fie foe foo.
   Correct some object start states and reading-related glitches in the endgame.
 
 1.9: 2020-08-27::
diff --git a/README.adoc b/README.adoc
index 03f249d..573bf7a 100644
--- a/README.adoc
+++ b/README.adoc
@@ -1,4 +1,6 @@
 = README for Open Adventure =
+// SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+// SPDX-License-Identifier: CC-BY-4.0
 
 If you are reading this anywhere but at http://www.catb.org/~esr/open-adventure
 you can go there for tarball downloads and other resources.
diff --git a/actions.c b/actions.c
index a2105f8..4f4ced1 100644
--- a/actions.c
+++ b/actions.c
@@ -1,9 +1,9 @@
 /*
- * Actions for the duneon-running code.
+ * Actions for the dungeon-running code.
  *
- * Copyright (c) 1977, 2005 by Will Crowther and Don Woods
- * Copyright (c) 2017 by Eric S. Raymond
- * SPDX-License-Identifier: BSD-2-clause
+ * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods
+ * SPDX-FileCopyrightText 2017 by Eric S. Raymond
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdlib.h>
@@ -34,7 +34,7 @@ static phase_codes_t attack(command_t command)
             obj = SNAKE;
             ++changes;
         }
-        if (AT(DRAGON) && game.prop[DRAGON] == DRAGON_BARS) {
+        if (AT(DRAGON) && game.objects[DRAGON].prop == DRAGON_BARS) {
             obj = DRAGON;
             ++changes;
         }
@@ -46,7 +46,7 @@ static phase_codes_t attack(command_t command)
             obj = OGRE;
             ++changes;
         }
-        if (HERE(BEAR) && game.prop[BEAR] == UNTAMED_BEAR) {
+        if (HERE(BEAR) && game.objects[BEAR].prop == UNTAMED_BEAR) {
             obj = BEAR;
             ++changes;
         }
@@ -83,13 +83,13 @@ static phase_codes_t attack(command_t command)
     }
     if (obj == VEND) {
         state_change(VEND,
-                     game.prop[VEND] == VEND_BLOCKS ? VEND_UNBLOCKS : VEND_BLOCKS);
+                     game.objects[VEND].prop == VEND_BLOCKS ? VEND_UNBLOCKS : VEND_BLOCKS);
 
         return GO_CLEAROBJ;
     }
 
     if (obj == BEAR) {
-        switch (game.prop[BEAR]) {
+        switch (game.objects[BEAR].prop) {
         case UNTAMED_BEAR:
             rspeak(BEAR_HANDS);
             break;
@@ -105,7 +105,7 @@ static phase_codes_t attack(command_t command)
         }
         return GO_CLEAROBJ;
     }
-    if (obj == DRAGON && game.prop[DRAGON] == DRAGON_BARS) {
+    if (obj == DRAGON && game.objects[DRAGON].prop == DRAGON_BARS) {
         /*  Fun stuff for dragon.  If he insists on attacking it, win!
          *  Set game.prop to dead, move dragon to central loc (still
          *  fixed), move rug there (not fixed), and move him there,
@@ -116,7 +116,7 @@ static phase_codes_t attack(command_t command)
             return GO_MOVE;
         }
         state_change(DRAGON, DRAGON_DEAD);
-        game.prop[RUG] = RUG_FLOOR;
+        game.objects[RUG].prop = RUG_FLOOR;
         /* Hardcoding LOC_SECRET5 as the dragon's death location is ugly.
          * The way it was computed before was worse; it depended on the
          * two dragon locations being LOC_SECRET4 and LOC_SECRET6 and
@@ -128,8 +128,8 @@ static phase_codes_t attack(command_t command)
         move(RUG, LOC_SECRET5);
         drop(BLOOD, LOC_SECRET5);
         for (obj_t i = 1; i <= NOBJECTS; i++) {
-            if (game.place[i] == objects[DRAGON].plac ||
-                game.place[i] == objects[DRAGON].fixd)
+            if (game.objects[i].place == objects[DRAGON].plac ||
+                game.objects[i].place == objects[DRAGON].fixd)
                 move(i, LOC_SECRET5);
         }
         game.loc = LOC_SECRET5;
@@ -145,10 +145,10 @@ static phase_codes_t attack(command_t command)
         DESTROY(OGRE);
         int dwarves = 0;
         for (int i = 1; i < PIRATE; i++) {
-            if (game.dloc[i] == game.loc) {
+            if (game.dwarves[i].loc == game.loc) {
                 ++dwarves;
-                game.dloc[i] = LOC_LONGWEST;
-                game.dseen[i] = false;
+                game.dwarves[i].loc = LOC_LONGWEST;
+                game.dwarves[i].seen = false;
             }
         }
         rspeak((dwarves > 1) ?
@@ -192,28 +192,34 @@ static phase_codes_t bigwords(vocab_t id)
  * word we've got. Last word zips the eggs back to the giant room (unless
  * already there). */
 {
-    if ((game.foobar == WORD_EMPTY && id == FEE) ||
-        (game.foobar == FEE && id == FIE) ||
-        (game.foobar == FIE && id == FOE) ||
-        (game.foobar == FOE && id == FOO) ||
-        (game.foobar == FOE && id == FUM)) {
+    int foobar = abs(game.foobar);
+
+    /* Only FEE can start a magic-word sequence. */
+    if ((foobar == WORD_EMPTY) && (id == FIE || id == FOE || id == FOO || id == FUM)) {
+	rspeak(NOTHING_HAPPENS);
+	return GO_CLEAROBJ;
+    }
+    
+    if ((foobar == WORD_EMPTY && id == FEE) ||
+        (foobar == FEE && id == FIE) ||
+        (foobar == FIE && id == FOE) ||
+        (foobar == FOE && id == FOO)) {
         game.foobar = id;
-        if ((id != FOO) && (id != FUM)) {
+        if (id != FOO) {
             rspeak(OK_MAN);
             return GO_CLEAROBJ;
         }
         game.foobar = WORD_EMPTY;
-        if (game.place[EGGS] == objects[EGGS].plac ||
+        if (game.objects[EGGS].place == objects[EGGS].plac ||
             (TOTING(EGGS) && game.loc == objects[EGGS].plac)) {
             rspeak(NOTHING_HAPPENS);
             return GO_CLEAROBJ;
-        } else if (id == FUM) {
-            goto fum;
         } else {
             /*  Bring back troll if we steal the eggs back from him before
              *  crossing. */
-            if (game.place[EGGS] == LOC_NOWHERE && game.place[TROLL] == LOC_NOWHERE && game.prop[TROLL] == TROLL_UNPAID)
-                game.prop[TROLL] = TROLL_PAIDONCE;
+            if (game.objects[EGGS].place == LOC_NOWHERE && game.objects[TROLL].place == LOC_NOWHERE
+		&& game.objects[TROLL].prop == TROLL_UNPAID)
+                game.objects[TROLL].prop = TROLL_PAIDONCE;
             if (HERE(EGGS))
                 pspeak(EGGS, look, true, EGGS_VANISHED);
             else if (game.loc == objects[EGGS].plac)
@@ -225,14 +231,11 @@ static phase_codes_t bigwords(vocab_t id)
             return GO_CLEAROBJ;
         }
     } else {
-fum:
-        if (game.loc == LOC_GIANTROOM) {
-            rspeak(START_OVER);
-        } else {
-            /* This is new behavior in Open Adventure - sounds better when
-             * player isn't in the Giant Room. */
-            rspeak(NOTHING_HAPPENS);
-        }
+	/* Magic-word sequence was started but is incorrect */
+	if (settings.oldstyle || game.seenbigwords)
+	    rspeak(START_OVER);
+	else
+	    rspeak(WELL_POINTLESS);
         game.foobar = WORD_EMPTY;
         return GO_CLEAROBJ;
     }
@@ -241,8 +244,7 @@ fum:
 static void blast(void)
 /*  Blast.  No effect unless you've got dynamite, which is a neat trick! */
 {
-    if (game.prop[ROD2] == STATE_NOTFOUND ||
-        !game.closed)
+    if (PROP_IS_NOTFOUND(ROD2) || !game.closed)
         rspeak(REQUIRES_DYNAMITE);
     else {
         if (HERE(ROD2)) {
@@ -272,11 +274,11 @@ static phase_codes_t vbreak(verb_t verb, obj_t obj)
             break;
         }
     case VASE:
-        if (game.prop[VASE] == VASE_WHOLE) {
+        if (game.objects[VASE].prop == VASE_WHOLE) {
             if (TOTING(VASE))
                 drop(VASE, game.loc);
             state_change(VASE, VASE_BROKEN);
-            game.fixed[VASE] = IS_FIXED;
+            game.objects[VASE].fixed = IS_FIXED;
             break;
         }
     /* FALLTHRU */
@@ -302,11 +304,11 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj)
 {
     if (obj == INTRANSITIVE) {
         /*  Carry, no object given yet.  OK if only one object present. */
-        if (game.atloc[game.loc] == NO_OBJECT ||
-            game.link[game.atloc[game.loc]] != 0 ||
+        if (game.locs[game.loc].atloc == NO_OBJECT ||
+            game.link[game.locs[game.loc].atloc] != 0 ||
             atdwrf(game.loc) > 0)
             return GO_UNKNOWN;
-        obj = game.atloc[game.loc];
+        obj = game.locs[game.loc].atloc;
     }
 
     if (TOTING(obj)) {
@@ -320,20 +322,20 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj)
         return GO_CLEAROBJ;
     }
 
-    if (game.fixed[obj] != IS_FREE) {
+    if (game.objects[obj].fixed != IS_FREE) {
         switch (obj) {
         case PLANT:
             /* Next guard tests whether plant is tiny or stashed */
-            rspeak(game.prop[PLANT] <= PLANT_THIRSTY ? DEEP_ROOTS : YOU_JOKING);
+            rspeak(game.objects[PLANT].prop <= PLANT_THIRSTY ? DEEP_ROOTS : YOU_JOKING);
             break;
         case BEAR:
-            rspeak( game.prop[BEAR] == SITTING_BEAR ? BEAR_CHAINED : YOU_JOKING);
+            rspeak( game.objects[BEAR].prop == SITTING_BEAR ? BEAR_CHAINED : YOU_JOKING);
             break;
         case CHAIN:
-            rspeak( game.prop[BEAR] != UNTAMED_BEAR ? STILL_LOCKED : YOU_JOKING);
+            rspeak( game.objects[BEAR].prop != UNTAMED_BEAR ? STILL_LOCKED : YOU_JOKING);
             break;
         case RUG:
-            rspeak(game.prop[RUG] == RUG_HOVER ? RUG_HOVERS : YOU_JOKING);
+            rspeak(game.objects[RUG].prop == RUG_HOVER ? RUG_HOVERS : YOU_JOKING);
             break;
         case URN:
             rspeak(URN_NOBUDGE);
@@ -353,15 +355,13 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj)
         return GO_CLEAROBJ;
     }
 
-    if (obj == WATER ||
-        obj == OIL) {
-        if (!HERE(BOTTLE) ||
-            LIQUID() != obj) {
+    if (obj == WATER || obj == OIL) {
+        if (!HERE(BOTTLE) || LIQUID() != obj) {
             if (!TOTING(BOTTLE)) {
                 rspeak(NO_CONTAINER);
                 return GO_CLEAROBJ;
             }
-            if (game.prop[BOTTLE] == EMPTY_BOTTLE) {
+            if (game.objects[BOTTLE].prop == EMPTY_BOTTLE) {
                 return (fill(verb, BOTTLE));
             } else
                 rspeak(BOTTLE_FULL);
@@ -376,8 +376,8 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj)
 
     }
 
-    if (obj == BIRD && game.prop[BIRD] != BIRD_CAGED && STASHED(BIRD) != BIRD_CAGED) {
-        if (game.prop[BIRD] == BIRD_FOREST_UNCAGED) {
+    if (obj == BIRD && game.objects[BIRD].prop != BIRD_CAGED && !PROP_IS_STASHED(BIRD)) {
+        if (game.objects[BIRD].prop == BIRD_FOREST_UNCAGED) {
             DESTROY(BIRD);
             rspeak(BIRD_CRAP);
             return GO_CLEAROBJ;
@@ -390,11 +390,10 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj)
             rspeak(BIRD_EVADES);
             return GO_CLEAROBJ;
         }
-        game.prop[BIRD] = BIRD_CAGED;
+        game.objects[BIRD].prop = BIRD_CAGED;
     }
-    if ((obj == BIRD ||
-         obj == CAGE) &&
-        (game.prop[BIRD] == BIRD_CAGED || STASHED(BIRD) == BIRD_CAGED)) {
+    if ((obj == BIRD || obj == CAGE) &&
+        (game.objects[BIRD].prop == BIRD_CAGED || PROP_STASHED(BIRD) == BIRD_CAGED)) {
         /* expression maps BIRD to CAGE and CAGE to BIRD */
         carry(BIRD + CAGE - obj, game.loc);
     }
@@ -402,11 +401,11 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj)
     carry(obj, game.loc);
 
     if (obj == BOTTLE && LIQUID() != NO_OBJECT)
-        game.place[LIQUID()] = CARRIED;
+        game.objects[LIQUID()].place = CARRIED;
 
-    if (GSTONE(obj) && game.prop[obj] != STATE_FOUND) {
-        game.prop[obj] = STATE_FOUND;
-        game.prop[CAVITY] = CAVITY_EMPTY;
+    if (GSTONE(obj) && !PROP_IS_FOUND(obj)) {
+        PROP_SET_FOUND(obj);
+        game.objects[CAVITY].prop = CAVITY_EMPTY;
     }
     rspeak(OK_MAN);
     return GO_CLEAROBJ;
@@ -416,36 +415,36 @@ static int chain(verb_t verb)
 /* Do something to the bear's chain */
 {
     if (verb != LOCK) {
-        if (game.prop[BEAR] == UNTAMED_BEAR) {
+        if (game.objects[BEAR].prop == UNTAMED_BEAR) {
             rspeak(BEAR_BLOCKS);
             return GO_CLEAROBJ;
         }
-        if (game.prop[CHAIN] == CHAIN_HEAP) {
+        if (game.objects[CHAIN].prop == CHAIN_HEAP) {
             rspeak(ALREADY_UNLOCKED);
             return GO_CLEAROBJ;
         }
-        game.prop[CHAIN] = CHAIN_HEAP;
-        game.fixed[CHAIN] = IS_FREE;
-        if (game.prop[BEAR] != BEAR_DEAD)
-            game.prop[BEAR] = CONTENTED_BEAR;
+        game.objects[CHAIN].prop = CHAIN_HEAP;
+        game.objects[CHAIN].fixed = IS_FREE;
+        if (game.objects[BEAR].prop != BEAR_DEAD)
+            game.objects[BEAR].prop = CONTENTED_BEAR;
 
-        switch (game.prop[BEAR]) {
+        switch (game.objects[BEAR].prop) {
         // LCOV_EXCL_START
         case BEAR_DEAD:
             /* Can't be reached until the bear can die in some way other
              * than a bridge collapse. Leave in in case this changes, but
              * exclude from coverage testing. */
-            game.fixed[BEAR] = IS_FIXED;
+            game.objects[BEAR].fixed = IS_FIXED;
             break;
         // LCOV_EXCL_STOP
         default:
-            game.fixed[BEAR] = IS_FREE;
+            game.objects[BEAR].fixed = IS_FREE;
         }
         rspeak(CHAIN_UNLOCKED);
         return GO_CLEAROBJ;
     }
 
-    if (game.prop[CHAIN] != CHAIN_HEAP) {
+    if (game.objects[CHAIN].prop != CHAIN_HEAP) {
         rspeak(ALREADY_LOCKED);
         return GO_CLEAROBJ;
     }
@@ -454,11 +453,11 @@ static int chain(verb_t verb)
         return GO_CLEAROBJ;
     }
 
-    game.prop[CHAIN] = CHAIN_FIXED;
+    game.objects[CHAIN].prop = CHAIN_FIXED;
 
     if (TOTING(CHAIN))
         drop(CHAIN, game.loc);
-    game.fixed[CHAIN] = IS_FIXED;
+    game.objects[CHAIN].fixed = IS_FIXED;
 
     rspeak(CHAIN_LOCKED);
     return GO_CLEAROBJ;
@@ -478,12 +477,12 @@ static phase_codes_t discard(verb_t verb, obj_t obj)
         return GO_CLEAROBJ;
     }
 
-    if (GSTONE(obj) && AT(CAVITY) && game.prop[CAVITY] != CAVITY_FULL) {
+    if (GSTONE(obj) && AT(CAVITY) && game.objects[CAVITY].prop != CAVITY_FULL) {
         rspeak(GEM_FITS);
-        game.prop[obj] = STATE_IN_CAVITY;
-        game.prop[CAVITY] = CAVITY_FULL;
-        if (HERE(RUG) && ((obj == EMERALD && game.prop[RUG] != RUG_HOVER) ||
-                          (obj == RUBY && game.prop[RUG] == RUG_HOVER))) {
+        game.objects[obj].prop = STATE_IN_CAVITY;
+        game.objects[CAVITY].prop = CAVITY_FULL;
+        if (HERE(RUG) && ((obj == EMERALD && game.objects[RUG].prop != RUG_HOVER) ||
+                          (obj == RUBY && game.objects[RUG].prop == RUG_HOVER))) {
             if (obj == RUBY)
                 rspeak(RUG_SETTLES);
             else if (TOTING(RUG))
@@ -491,8 +490,8 @@ static phase_codes_t discard(verb_t verb, obj_t obj)
             else
                 rspeak(RUG_RISES);
             if (!TOTING(RUG) || obj == RUBY) {
-                int k = (game.prop[RUG] == RUG_HOVER) ? RUG_FLOOR : RUG_HOVER;
-                game.prop[RUG] = k;
+                int k = (game.objects[RUG].prop == RUG_HOVER) ? RUG_FLOOR : RUG_HOVER;
+                game.objects[RUG].prop = k;
                 if (k == RUG_HOVER)
                     k = objects[SAPPH].plac;
                 move(RUG + NOBJECTS, k);
@@ -512,7 +511,7 @@ static phase_codes_t discard(verb_t verb, obj_t obj)
     if (LIQUID() == obj)
         obj = BOTTLE;
     if (obj == BOTTLE && LIQUID() != NO_OBJECT) {
-        game.place[LIQUID()] = LOC_NOWHERE;
+        game.objects[LIQUID()].place = LOC_NOWHERE;
     }
 
     if (obj == BEAR && AT(TROLL)) {
@@ -531,19 +530,19 @@ static phase_codes_t discard(verb_t verb, obj_t obj)
             state_change(VASE, AT(PILLOW)
                          ? VASE_WHOLE
                          : VASE_DROPPED);
-            if (game.prop[VASE] != VASE_WHOLE)
-                game.fixed[VASE] = IS_FIXED;
+            if (game.objects[VASE].prop != VASE_WHOLE)
+                game.objects[VASE].fixed = IS_FIXED;
             drop(obj, game.loc);
             return GO_CLEAROBJ;
         }
     }
 
-    if (obj == CAGE && game.prop[BIRD] == BIRD_CAGED) {
+    if (obj == CAGE && game.objects[BIRD].prop == BIRD_CAGED) {
         drop(BIRD, game.loc);
     }
 
     if (obj == BIRD) {
-        if (AT(DRAGON) && game.prop[DRAGON] == DRAGON_BARS) {
+        if (AT(DRAGON) && game.objects[DRAGON].prop == DRAGON_BARS) {
             rspeak(BIRD_BURNT);
             DESTROY(BIRD);
             return GO_CLEAROBJ;
@@ -554,11 +553,11 @@ static phase_codes_t discard(verb_t verb, obj_t obj)
                 return GO_DWARFWAKE;
             DESTROY(SNAKE);
             /* Set game.prop for use by travel options */
-            game.prop[SNAKE] = SNAKE_CHASED;
+            game.objects[SNAKE].prop = SNAKE_CHASED;
         } else
             rspeak(OK_MAN);
 
-        game.prop[BIRD] = FOREST(game.loc) ? BIRD_FOREST_UNCAGED : BIRD_UNCAGED;
+        game.objects[BIRD].prop = FOREST(game.loc) ? BIRD_FOREST_UNCAGED : BIRD_UNCAGED;
         drop(obj, game.loc);
         return GO_CLEAROBJ;
     }
@@ -589,7 +588,7 @@ static phase_codes_t drink(verb_t verb, obj_t obj)
         return GO_CLEAROBJ;
     }
     if (LIQUID() == WATER && HERE(BOTTLE)) {
-        game.place[WATER] = LOC_NOWHERE;
+        game.objects[WATER].place = LOC_NOWHERE;
         state_change(BOTTLE, EMPTY_BOTTLE);
         return GO_CLEAROBJ;
     }
@@ -632,9 +631,9 @@ static phase_codes_t extinguish(verb_t verb, obj_t obj)
 /* Extinguish.  Lamp, urn, dragon/volcano (nice try). */
 {
     if (obj == INTRANSITIVE) {
-        if (HERE(LAMP) && game.prop[LAMP] == LAMP_BRIGHT)
+        if (HERE(LAMP) && game.objects[LAMP].prop == LAMP_BRIGHT)
             obj = LAMP;
-        if (HERE(URN) && game.prop[URN] == URN_LIT)
+        if (HERE(URN) && game.objects[URN].prop == URN_LIT)
             obj = URN;
         if (obj == INTRANSITIVE)
             return GO_UNKNOWN;
@@ -642,7 +641,7 @@ static phase_codes_t extinguish(verb_t verb, obj_t obj)
 
     switch (obj) {
     case URN:
-        if (game.prop[URN] != URN_EMPTY) {
+        if (game.objects[URN].prop != URN_EMPTY) {
             state_change(URN, URN_DARK);
         } else {
             pspeak(URN, change, true, URN_DARK);
@@ -673,7 +672,7 @@ static phase_codes_t feed(verb_t verb, obj_t obj)
         rspeak(BIRD_PINING);
         break;
     case DRAGON:
-        if (game.prop[DRAGON] != DRAGON_BARS)
+        if (game.objects[DRAGON].prop != DRAGON_BARS)
             rspeak(RIDICULOUS_ATTEMPT);
         else
             rspeak(NOTHING_EDIBLE);
@@ -696,15 +695,15 @@ static phase_codes_t feed(verb_t verb, obj_t obj)
             speak(actions[verb].message);
         break;
     case BEAR:
-        if (game.prop[BEAR] == BEAR_DEAD) {
+        if (game.objects[BEAR].prop == BEAR_DEAD) {
             rspeak(RIDICULOUS_ATTEMPT);
             break;
         }
-        if (game.prop[BEAR] == UNTAMED_BEAR) {
+        if (game.objects[BEAR].prop == UNTAMED_BEAR) {
             if (HERE(FOOD)) {
                 DESTROY(FOOD);
-                game.fixed[AXE] = IS_FREE;
-                game.prop[AXE] = AXE_HERE;
+                game.objects[AXE].fixed = IS_FREE;
+                game.objects[AXE].prop = AXE_HERE;
                 state_change(BEAR, SITTING_BEAR);
             } else
                 rspeak(NOTHING_EDIBLE);
@@ -738,14 +737,14 @@ phase_codes_t fill(verb_t verb, obj_t obj)
             return GO_CLEAROBJ;
         }
         rspeak(SHATTER_VASE);
-        game.prop[VASE] = VASE_BROKEN;
-        game.fixed[VASE] = IS_FIXED;
+        game.objects[VASE].prop = VASE_BROKEN;
+        game.objects[VASE].fixed = IS_FIXED;
         drop(VASE, game.loc);
         return GO_CLEAROBJ;
     }
 
     if (obj == URN) {
-        if (game.prop[URN] != URN_EMPTY) {
+        if (game.objects[URN].prop != URN_EMPTY) {
             rspeak(FULL_URN);
             return GO_CLEAROBJ;
         }
@@ -756,12 +755,12 @@ phase_codes_t fill(verb_t verb, obj_t obj)
         int k = LIQUID();
         switch (k) {
         case WATER:
-            game.prop[BOTTLE] = EMPTY_BOTTLE;
+            game.objects[BOTTLE].prop = EMPTY_BOTTLE;
             rspeak(WATER_URN);
             break;
         case OIL:
-            game.prop[URN] = URN_DARK;
-            game.prop[BOTTLE] = EMPTY_BOTTLE;
+            game.objects[URN].prop = URN_DARK;
+            game.objects[BOTTLE].prop = EMPTY_BOTTLE;
             rspeak(OIL_URN);
             break;
         case NO_OBJECT:
@@ -769,7 +768,7 @@ phase_codes_t fill(verb_t verb, obj_t obj)
             rspeak(FILL_INVALID);
             return GO_CLEAROBJ;
         }
-        game.place[k] = LOC_NOWHERE;
+        game.objects[k].place = LOC_NOWHERE;
         return GO_CLEAROBJ;
     }
     if (obj != INTRANSITIVE && obj != BOTTLE) {
@@ -779,7 +778,7 @@ phase_codes_t fill(verb_t verb, obj_t obj)
     if (obj == INTRANSITIVE && !HERE(BOTTLE))
         return GO_UNKNOWN;
 
-    if (HERE(URN) && game.prop[URN] != URN_EMPTY) {
+    if (HERE(URN) && game.objects[URN].prop != URN_EMPTY) {
         rspeak(URN_NOPOUR);
         return GO_CLEAROBJ;
     }
@@ -796,7 +795,7 @@ phase_codes_t fill(verb_t verb, obj_t obj)
                  ? OIL_BOTTLE
                  : WATER_BOTTLE);
     if (TOTING(BOTTLE))
-        game.place[LIQUID()] = CARRIED;
+        game.objects[LIQUID()].place = CARRIED;
     return GO_CLEAROBJ;
 }
 
@@ -813,10 +812,8 @@ static phase_codes_t find(verb_t verb, obj_t obj)
         return GO_CLEAROBJ;
     }
 
-    if (AT(obj) ||
-        (LIQUID() == obj && AT(BOTTLE)) ||
-        obj == LIQLOC(game.loc) ||
-        (obj == DWARF && atdwrf(game.loc) > 0)) {
+    if (AT(obj) || (LIQUID() == obj && AT(BOTTLE)) ||
+        obj == LIQLOC(game.loc) || (obj == DWARF && atdwrf(game.loc) > 0)) {
         rspeak(YOU_HAVEIT);
         return GO_CLEAROBJ;
     }
@@ -834,7 +831,7 @@ static phase_codes_t fly(verb_t verb, obj_t obj)
             rspeak(FLAP_ARMS);
             return GO_CLEAROBJ;
         }
-        if (game.prop[RUG] != RUG_HOVER) {
+        if (game.objects[RUG].prop != RUG_HOVER) {
             rspeak(RUG_NOTHING2);
             return GO_CLEAROBJ;
         }
@@ -845,7 +842,7 @@ static phase_codes_t fly(verb_t verb, obj_t obj)
         speak(actions[verb].message);
         return GO_CLEAROBJ;
     }
-    if (game.prop[RUG] != RUG_HOVER) {
+    if (game.objects[RUG].prop != RUG_HOVER) {
         rspeak(RUG_NOTHING1);
         return GO_CLEAROBJ;
     }
@@ -874,8 +871,7 @@ static phase_codes_t inven(void)
 {
     bool empty = true;
     for (obj_t i = 1; i <= NOBJECTS; i++) {
-        if (i == BEAR ||
-            !TOTING(i))
+        if (i == BEAR || !TOTING(i))
             continue;
         if (empty) {
             rspeak(NOW_HOLDING);
@@ -895,11 +891,11 @@ static phase_codes_t light(verb_t verb, obj_t obj)
 {
     if (obj == INTRANSITIVE) {
         int selects = 0;
-        if (HERE(LAMP) && game.prop[LAMP] == LAMP_DARK && game.limit >= 0) {
+        if (HERE(LAMP) && game.objects[LAMP].prop == LAMP_DARK && game.limit >= 0) {
             obj = LAMP;
             selects++;
         }
-        if (HERE(URN) && game.prop[URN] == URN_DARK) {
+        if (HERE(URN) && game.objects[URN].prop == URN_DARK) {
             obj =  URN;
             selects++;
         }
@@ -909,7 +905,7 @@ static phase_codes_t light(verb_t verb, obj_t obj)
 
     switch (obj) {
     case URN:
-        state_change(URN, game.prop[URN] == URN_EMPTY ?
+        state_change(URN, game.objects[URN].prop == URN_EMPTY ?
                      URN_EMPTY :
                      URN_LIT);
         break;
@@ -929,7 +925,7 @@ static phase_codes_t light(verb_t verb, obj_t obj)
 }
 
 static phase_codes_t listen(void)
-/*  Listen.  Intransitive only.  Print stuff based on object sound proprties. */
+/*  Listen.  Intransitive only.  Print stuff based on object sound properties. */
 {
     bool soundlatch = false;
     vocab_t sound = locations[game.loc].sound;
@@ -940,11 +936,9 @@ static phase_codes_t listen(void)
         soundlatch = true;
     }
     for (obj_t i = 1; i <= NOBJECTS; i++) {
-        if (!HERE(i) ||
-            objects[i].sounds[0] == NULL ||
-            game.prop[i] < 0)
+        if (!HERE(i) || objects[i].sounds[0] == NULL || PROP_IS_STASHED_OR_UNSEEN(i))
             continue;
-        int mi =  game.prop[i];
+        int mi =  game.objects[i].prop;
         /* (ESR) Some unpleasant magic on object states here. Ideally
          * we'd have liked the bird to be a normal object that we can
          * use state_change() on; can't do it, because there are
@@ -1033,7 +1027,7 @@ static phase_codes_t lock(verb_t verb, obj_t obj)
             rspeak(OYSTER_OPENS);
         break;
     case DOOR:
-        rspeak((game.prop[DOOR] == DOOR_UNRUSTED) ? OK_MAN : RUSTY_DOOR);
+        rspeak((game.objects[DOOR].prop == DOOR_UNRUSTED) ? OK_MAN : RUSTY_DOOR);
         break;
     case CAGE:
         rspeak( NO_LOCK);
@@ -1052,9 +1046,8 @@ static phase_codes_t pour(verb_t verb, obj_t obj)
 /*  Pour.  If no object, or object is bottle, assume contents of bottle.
  *  special tests for pouring water or oil on plant or rusty door. */
 {
-    if (obj == BOTTLE ||
-        obj == INTRANSITIVE)
-        obj = LIQUID();
+    if (obj == BOTTLE || obj == INTRANSITIVE)
+	obj = LIQUID();
     if (obj == NO_OBJECT)
         return GO_UNKNOWN;
     if (!TOTING(obj)) {
@@ -1066,20 +1059,19 @@ static phase_codes_t pour(verb_t verb, obj_t obj)
         rspeak(CANT_POUR);
         return GO_CLEAROBJ;
     }
-    if (HERE(URN) && game.prop[URN] == URN_EMPTY)
+    if (HERE(URN) && game.objects[URN].prop == URN_EMPTY)
         return fill(verb, URN);
-    game.prop[BOTTLE] = EMPTY_BOTTLE;
-    game.place[obj] = LOC_NOWHERE;
-    if (!(AT(PLANT) ||
-          AT(DOOR))) {
+    game.objects[BOTTLE].prop = EMPTY_BOTTLE;
+    game.objects[obj].place = LOC_NOWHERE;
+    if (!(AT(PLANT) || AT(DOOR))) {
         rspeak(GROUND_WET);
         return GO_CLEAROBJ;
     }
     if (!AT(DOOR)) {
         if (obj == WATER) {
             /* cycle through the three plant states */
-            state_change(PLANT, MOD(game.prop[PLANT] + 1, 3));
-            game.prop[PLANT2] = game.prop[PLANT];
+            state_change(PLANT, MOD(game.objects[PLANT].prop + 1, 3));
+            game.objects[PLANT2].prop = game.objects[PLANT].prop;
             return GO_MOVE;
         } else {
             rspeak(SHAKING_LEAVES);
@@ -1107,12 +1099,10 @@ static phase_codes_t read(command_t command)
     if (command.obj == INTRANSITIVE) {
         command.obj = NO_OBJECT;
         for (int i = 1; i <= NOBJECTS; i++) {
-            if (HERE(i) && objects[i].texts[0] != NULL && game.prop[i] >= 0)
+            if (HERE(i) && objects[i].texts[0] != NULL && !PROP_IS_STASHED(i))
                 command.obj = command.obj * NOBJECTS + i;
         }
-        if (command.obj > NOBJECTS ||
-            command.obj == NO_OBJECT ||
-            DARK(game.loc))
+        if (command.obj > NOBJECTS || command.obj == NO_OBJECT || DARK(game.loc))
             return GO_UNKNOWN;
     }
 
@@ -1126,11 +1116,10 @@ static phase_codes_t read(command_t command)
         } else {
             pspeak(OYSTER, hear, true, 1);	// Not really a sound, but oh well.
         }
-    } else if (objects[command.obj].texts[0] == NULL ||
-               game.prop[command.obj] == STATE_NOTFOUND) {
+    } else if (objects[command.obj].texts[0] == NULL || PROP_IS_NOTFOUND(command.obj)) {
         speak(actions[command.verb].message);
     } else
-        pspeak(command.obj, study, true, game.prop[command.obj]);
+        pspeak(command.obj, study, true, game.objects[command.obj].prop);
     return GO_CLEAROBJ;
 }
 
@@ -1142,7 +1131,7 @@ static phase_codes_t reservoir(void)
         return GO_CLEAROBJ;
     } else {
         state_change(RESER,
-                     game.prop[RESER] == WATERS_PARTED ? WATERS_UNPARTED : WATERS_PARTED);
+                     game.objects[RESER].prop == WATERS_PARTED ? WATERS_UNPARTED : WATERS_PARTED);
         if (AT(RESER))
             return GO_CLEAROBJ;
         else {
@@ -1157,10 +1146,10 @@ static phase_codes_t reservoir(void)
 static phase_codes_t rub(verb_t verb, obj_t obj)
 /* Rub.  Yields various snide remarks except for lit urn. */
 {
-    if (obj == URN && game.prop[URN] == URN_LIT) {
+    if (obj == URN && game.objects[URN].prop == URN_LIT) {
         DESTROY(URN);
         drop(AMBER, game.loc);
-        game.prop[AMBER] = AMBER_IN_ROCK;
+        game.objects[AMBER].prop = AMBER_IN_ROCK;
         --game.tally;
         drop(CAVITY, game.loc);
         rspeak(URN_GENIES);
@@ -1234,16 +1223,16 @@ static phase_codes_t throwit(command_t command)
         return (discard(command.verb, command.obj));
     else {
         if (atdwrf(game.loc) <= 0) {
-            if (AT(DRAGON) && game.prop[DRAGON] == DRAGON_BARS)
+            if (AT(DRAGON) && game.objects[DRAGON].prop == DRAGON_BARS)
                 return throw_support(DRAGON_SCALES);
             if (AT(TROLL))
                 return throw_support(TROLL_RETURNS);
             if (AT(OGRE))
                 return throw_support(OGRE_DODGE);
-            if (HERE(BEAR) && game.prop[BEAR] == UNTAMED_BEAR) {
+            if (HERE(BEAR) && game.objects[BEAR].prop == UNTAMED_BEAR) {
                 /* This'll teach him to throw the axe at the bear! */
                 drop(AXE, game.loc);
-                game.fixed[AXE] = IS_FIXED;
+                game.objects[AXE].fixed = IS_FIXED;
                 juggle(BEAR);
                 state_change(AXE, AXE_LOST);
                 return GO_CLEAROBJ;
@@ -1256,8 +1245,8 @@ static phase_codes_t throwit(command_t command)
             return throw_support(DWARF_DODGES);
         } else {
             int i = atdwrf(game.loc);
-            game.dseen[i] = false;
-            game.dloc[i] = LOC_NOWHERE;
+            game.dwarves[i].seen = false;
+            game.dwarves[i].loc = LOC_NOWHERE;
             return throw_support((++game.dkill == 1) ?
                                  DWARF_SMOKE :
                                  KILLED_DWARF);
@@ -1268,8 +1257,7 @@ static phase_codes_t throwit(command_t command)
 static phase_codes_t wake(verb_t verb, obj_t obj)
 /* Wake.  Only use is to disturb the dwarves. */
 {
-    if (obj != DWARF ||
-        !game.closed) {
+    if (obj != DWARF || !game.closed) {
         speak(actions[verb].message);
         return GO_CLEAROBJ;
     } else {
@@ -1299,11 +1287,7 @@ static phase_codes_t waste(verb_t verb, turn_t turns)
 static phase_codes_t wave(verb_t verb, obj_t obj)
 /* Wave.  No effect unless waving rod at fissure or at bird. */
 {
-    if (obj != ROD ||
-        !TOTING(obj) ||
-        (!HERE(BIRD) &&
-         (game.closng ||
-          !AT(FISSURE)))) {
+    if (obj != ROD || !TOTING(obj) || (!HERE(BIRD) && (game.closng || !AT(FISSURE)))) {
         speak(((!TOTING(obj)) && (obj != ROD ||
                                   !TOTING(ROD2))) ?
               arbitrary_messages[ARENT_CARRYING] :
@@ -1311,33 +1295,33 @@ static phase_codes_t wave(verb_t verb, obj_t obj)
         return GO_CLEAROBJ;
     }
 
-    if (game.prop[BIRD] == BIRD_UNCAGED && game.loc == game.place[STEPS] && game.prop[JADE] == STATE_NOTFOUND) {
+    if (game.objects[BIRD].prop == BIRD_UNCAGED && game.loc == game.objects[STEPS].place
+	&& PROP_IS_NOTFOUND(JADE)) {
         drop(JADE, game.loc);
-        game.prop[JADE] = STATE_FOUND;
+        PROP_SET_FOUND(JADE);
         --game.tally;
         rspeak(NECKLACE_FLY);
         return GO_CLEAROBJ;
     } else {
         if (game.closed) {
-            rspeak((game.prop[BIRD] == BIRD_CAGED) ?
+            rspeak((game.objects[BIRD].prop == BIRD_CAGED) ?
                    CAGE_FLY :
                    FREE_FLY);
             return GO_DWARFWAKE;
         }
-        if (game.closng ||
-            !AT(FISSURE)) {
-            rspeak((game.prop[BIRD] == BIRD_CAGED) ?
+        if (game.closng || !AT(FISSURE)) {
+            rspeak((game.objects[BIRD].prop == BIRD_CAGED) ?
                    CAGE_FLY :
                    FREE_FLY);
             return GO_CLEAROBJ;
         }
         if (HERE(BIRD))
-            rspeak((game.prop[BIRD] == BIRD_CAGED) ?
+            rspeak((game.objects[BIRD].prop == BIRD_CAGED) ?
                    CAGE_FLY :
                    FREE_FLY);
 
         state_change(FISSURE,
-                     game.prop[FISSURE] == BRIDGED ? UNBRIDGED : BRIDGED);
+                     game.objects[FISSURE].prop == BRIDGED ? UNBRIDGED : BRIDGED);
         return GO_CLEAROBJ;
     }
 }
@@ -1370,10 +1354,10 @@ phase_codes_t action(command_t command)
         else if (!game.closed && ((LIQUID() == command.obj && HERE(BOTTLE)) ||
                                   command.obj == LIQLOC(game.loc)))
             /* FALL THROUGH */;
-        else if (command.obj == OIL && HERE(URN) && game.prop[URN] != URN_EMPTY) {
+        else if (command.obj == OIL && HERE(URN) && game.objects[URN].prop != URN_EMPTY) {
             command.obj = URN;
             /* FALL THROUGH */;
-        } else if (command.obj == PLANT && AT(PLANT2) && game.prop[PLANT2] != PLANT_THIRSTY) {
+        } else if (command.obj == PLANT && AT(PLANT2) && game.objects[PLANT2].prop != PLANT_THIRSTY) {
             command.obj = PLANT2;
             /* FALL THROUGH */;
         } else if (command.obj == KNIFE && game.knfloc == game.loc) {
@@ -1404,8 +1388,7 @@ phase_codes_t action(command_t command)
              * will do here. We're preventing interpretation as an intransitive
              * verb when the word is unknown. */
             command.obj = command.word[1].raw[0] != '\0' ? KEYS : NO_OBJECT;
-        if (command.obj == NO_OBJECT ||
-            command.obj == INTRANSITIVE) {
+        if (command.obj == NO_OBJECT || command.obj == INTRANSITIVE) {
             /*  Analyse an intransitive verb (ie, no object given yet). */
             switch (command.verb) {
             case CARRY:
diff --git a/advent.adoc b/advent.adoc
index fa69ddc..db55ab2 100644
--- a/advent.adoc
+++ b/advent.adoc
@@ -1,5 +1,7 @@
 = advent(6) =
 :doctype: manpage
+// SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+// SPDX-License-Identifier: CC-BY-4.0
 
 == NAME ==
 advent - Colossal Cave Adventure
@@ -8,7 +10,7 @@ advent - Colossal Cave Adventure
 *advent* [-l logfile] [-o] [-r savefile] [script...]
 
 == DESCRIPTION ==
-The original Colossal Cave Adventure from 1976-77 was the origin of all
+The original Colossal Cave Adventure from 1976-1977 was the origin of all
 later text adventures, dungeon-crawl (computer) games, and computer-hosted
 roleplaying games.
 
@@ -18,19 +20,21 @@ adventure".  To learn more about the changes since the 350-point
 original, type 'news' at the command prompt.
 
 There is an 'adventure' in the BSD games package that is a C port by
-Jim Gillogly of the 1976 ancestor of this game.  To avoid a name
+Jim Gillogly of the Don Woods's 1977 version of this game.  To avoid a name
 collision, this game builds as 'advent', reflecting the fact that the
 PDP-10 on which the game originally ran limited filenames to 6 characters.
 
 This version is released as open source with the permission and
 encouragement of the original authors.
 
-Unlike the original, this version supports use of your arrow keys to edit
-your command line in place.  Basic Emacs keystrokes are supported, and
-your up/down arrows access a command history.
+Unlike the original, this version has a command prompt and supports
+use of your arrow keys to edit your command line in place.  Basic
+Emacs keystrokes are supported, and your up/down arrows access a
+command history.
 
-Otherwise, the "version" command is about the only way to tell you're not
-running Don's original.
+Some minor bugs and message typos have been fixed.  Otherwise, the
+"version" command is almost the only way to tell you're not running
+Don's 1977 version.
 
 To exit the game, type Ctrl-D (EOF).
 
@@ -42,12 +46,15 @@ There have been no gameplay changes.
 
 -r:: Restore game from specified file
 
--o:: Old-style.  Restores original interface, no prompt or line editing.
+-a:: Load from specified file and autosave to it on exit or signal.
+
+-o:: Old-style.  Reverts some minor cosmetic fixes in game
+     messages. Restores original interface, no prompt or line editing.
      Also ignores new-school one-letter commands l, x, g, z, i. Also
      case-smashes and truncates unrecognized text when echoed.
 
 Normally, game input is taken from standard input.  If script file
-arguments are given, input is taken fron them instead.  A script file
+arguments are given, input is taken from them instead.  A script file
 argument of '-' is taken as a directive to read from standard input.
 
 == BUGS ==
diff --git a/advent.desktop b/advent.desktop
index d41c896..fdc2f26 100644
--- a/advent.desktop
+++ b/advent.desktop
@@ -1,3 +1,5 @@
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 [Desktop Entry]
 Type=Application
 Name=Open Adventure
diff --git a/advent.h b/advent.h
index a2c1eb0..946fcae 100644
--- a/advent.h
+++ b/advent.h
@@ -1,3 +1,10 @@
+/*
+ * Dungeon types and macros.
+ *
+ * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods
+ * SPDX-FileCopyrightText: 2017 by Eric S. Raymond
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdbool.h>
@@ -13,7 +20,7 @@
 #define LCG_M 1048576L
 
 #define LINESIZE       1024
-#define TOKLEN         5          // # sigificant characters in a token */
+#define TOKLEN         5          // # outputting characters in a token */
 #define NDWARVES       6          // number of dwarves
 #define PIRATE         NDWARVES   // must be NDWARVES-1 when zero-origin
 #define DALTLC         LOC_NUGGET // alternate dwarf location
@@ -27,12 +34,13 @@
 #define BATTERYLIFE    2500       // turn limit increment from batteries
 #define WORD_NOT_FOUND -1         // "Word not found" flag value for the vocab hash functions.
 #define WORD_EMPTY     0          // "Word empty" flag value for the vocab hash functions
+#define PIT_KILL_PROB  35	  // Percentage probability of dying from fall in pit.
 #define CARRIED        -1         // Player is toting it
 #define READ_MODE      "rb"       // b is not needed for POSIX but harmless
 #define WRITE_MODE     "wb"       // b is not needed for POSIX but harmless
 
 /* Special object-state values - integers > 0 are object-specific */
-#define STATE_NOTFOUND  -1	  // 'Not found" state of treasures */
+#define STATE_NOTFOUND  -1	  // 'Not found" state of treasures
 #define STATE_FOUND	0	  // After discovered, before messed with
 #define STATE_IN_CAVITY	1	  // State value common to all gemstones
 
@@ -40,10 +48,58 @@
 #define IS_FIXED -1
 #define IS_FREE 0
 
-/* Map a state property value to a negative range, where the object cannot be
- * picked up but the value can be recovered later.  Avoid colliding with -1,
- * which has its own meaning. */
-#define STASHED(obj)	(-1 - game.prop[obj])
+#ifndef FOUNDBOOL
+/* (ESR) It is fitting that translation of the original ADVENT should
+ * have left us a maze of twisty little conditionals that resists all
+ * understanding.  Setting and use of what is now the per-object state
+ * member (which used to be an array of its own) is our mystery. This
+ * state tangles together information about whether the object is a
+ * treasure, whether the player has seen it yet, and its activation
+ * state.
+ *
+ * Things we think we know:
+ *
+ * STATE_NOTFOUND is only set on treasures. Non-treasures start the
+ * game in STATE_FOUND.
+ *
+ * PROP_STASHED is supposed to map a state property value to a
+ * negative range, where the object cannot be picked up but the value
+ * can be recovered later.  Various objects get this property when
+ * the cave starts to close. On;y seems to be signifucant for the bird 
+ * and readable objects, notably the clam/oyster - but the code around
+ * those test is difficult to read.
+ */
+#define PROP_STASHIFY(n)	(-1 - (n))
+#define PROP_IS_STASHED(obj)	(game.objects[obj].prop < STATE_NOTFOUND)
+#define PROP_IS_NOTFOUND(obj)	(game.objects[obj].prop == STATE_NOTFOUND)
+#define PROP_IS_FOUND(obj)	(game.objects[obj].prop == STATE_FOUND)
+#define PROP_IS_STASHED_OR_UNSEEN(obj)	(game.objects[obj].prop < 0)
+#define PROP_SET_FOUND(obj)	(game.objects[obj].prop = STATE_FOUND)
+#define PROP_SET_NOT_FOUND(obj)	(game.objects[obj].prop = STATE_NOTFOUND)
+#define PROP_IS_NOTFOUND2(g, o)	(g.objects[o].prop == STATE_NOTFOUND)
+#define PROP_IS_INVALID(val)	(val < -MAX_STATE - 1 || val > MAX_STATE)
+#else
+/* (ESR) Only the boldest of adventurers will explore here.  This
+ * alternate set of definitions for the macros above was an attempt to
+ * break from out of the state encoding a per-object "found" member
+ * telling whether or not the player has seen the object. 
+ *
+ * What's broken when you try to use thus is
+ * PROP_IS_STASHED_OR_UNSEEN. The symptom is game.tally getting
+ * decremented on non-treasures.
+ */
+#define PROP_STASHIFY(n)	(-(n))
+#define PROP_IS_STASHED(obj)	(game.objects[obj].prop < 0)
+#define PROP_IS_NOTFOUND(obj)	(!game.objects[obj].found)
+#define PROP_IS_FOUND(obj)	(game.objects[obj].found && game.objects[obj].prop == 0)
+#define PROP_IS_STASHED_OR_UNSEEN(obj)	(!game.objects[obj].found || game.objects[obj].prop < 0)
+#define PROP_SET_FOUND(obj)	do {game.objects[obj].found = true; game.objects[obj].prop = STATE_FOUND;} while(0)
+#define PROP_SET_NOT_FOUND(obj)	game.objects[obj].found = false
+#define PROP_IS_NOTFOUND2(g, o)	(!g.objects[o].found)
+#define PROP_IS_INVALID(val)	(val < -MAX_STATE || val > MAX_STATE)
+#define PROP_SET_SEEN(obj)	game.objects[object].found = true
+#endif
+#define PROP_STASHED(obj)	PROP_STASHIFY(game.objects[obj].prop)
 
 #define PROMPT	"> "
 
@@ -68,14 +124,14 @@
  */
 #define DESTROY(N)   move(N, LOC_NOWHERE)
 #define MOD(N,M)     ((N) % (M))
-#define TOTING(OBJ)  (game.place[OBJ] == CARRIED)
-#define AT(OBJ)      (game.place[OBJ] == game.loc || game.fixed[OBJ] == game.loc)
+#define TOTING(OBJ)  (game.objects[OBJ].place == CARRIED)
+#define AT(OBJ)      (game.objects[OBJ].place == game.loc || game.objects[OBJ].fixed == game.loc)
 #define HERE(OBJ)    (AT(OBJ) || TOTING(OBJ))
 #define CNDBIT(L,N)  (tstbit(conditions[L],N))
-#define LIQUID()     (game.prop[BOTTLE] == WATER_BOTTLE? WATER : game.prop[BOTTLE] == OIL_BOTTLE ? OIL : NO_OBJECT )
+#define LIQUID()     (game.objects[BOTTLE].prop == WATER_BOTTLE? WATER : game.objects[BOTTLE].prop == OIL_BOTTLE ? OIL : NO_OBJECT )
 #define LIQLOC(LOC)  (CNDBIT((LOC),COND_FLUID)? CNDBIT((LOC),COND_OILY) ? OIL : WATER : NO_OBJECT)
 #define FORCED(LOC)  CNDBIT(LOC, COND_FORCED)
-#define DARK(DUMMY)  (!CNDBIT(game.loc,COND_LIT) && (game.prop[LAMP] == LAMP_DARK || !HERE(LAMP)))
+#define DARK(DUMMY)  (!CNDBIT(game.loc,COND_LIT) && (game.objects[LAMP].prop == LAMP_DARK || !HERE(LAMP)))
 #define PCT(N)       (randrange(100) < (N))
 #define GSTONE(OBJ)  ((OBJ) == EMERALD || (OBJ) == RUBY || (OBJ) == AMBER || (OBJ) == SAPPH)
 #define FOREST(LOC)  CNDBIT(LOC, COND_FOREST)
@@ -108,7 +164,6 @@ typedef enum scorebonus {none, splatter, defeat, victory} score_t;
 
 /* Phase codes for action returns.
  * These were at one time FORTRAN line numbers.
- * The values don't matter, but perturb their order at your peril.
  */
 typedef enum {
     GO_TERMINATE,
@@ -160,7 +215,7 @@ struct game_t {
     int holdng;                  // number of objects being carried
     int igo;                     // # uses of "go" instead of a direction
     int iwest;                   // # times he's said "west" instead of "w"
-    int knfloc;                  // knife location; 0 if none, -1 after caveat
+    loc_t knfloc;                // knife location; LOC_NOWERE if none, -1 after caveat
     turn_t limit;                // lifetime of lamp
     loc_t loc;                   // where player is now
     loc_t newloc;                // where player is going
@@ -171,21 +226,36 @@ struct game_t {
     int saved;                   // point penalty for saves
     int tally;                   // count of treasures gained
     int thresh;                  // current threshold for endgame scoring tier
-    turn_t trndex;               // FIXME: not used, remove on next format bump
+    bool seenbigwords;           // have we red the graffiti in the Giant's Room? 
     turn_t trnluz;               // # points lost so far due to turns used
     turn_t turns;                // counts commands given (ignores yes/no)
     char zzword[TOKLEN + 1];     // randomly generated magic word from bird
-    int abbrev[NLOCATIONS + 1];  // has location been seen?
-    int atloc[NLOCATIONS + 1];   // head of object linked list per location
-    int dseen[NDWARVES + 1];     // true if dwarf has seen him
-    loc_t dloc[NDWARVES + 1];    // location of dwarves, initially hard-wired in
-    loc_t odloc[NDWARVES + 1];   // prior loc of each dwarf, initially garbage
-    loc_t fixed[NOBJECTS + 1];   // fixed location of object (if  not IS_FREE)
+    struct {
+	int abbrev;              // has location been seen?
+	int atloc;               // head of object linked list per location
+    } locs[NLOCATIONS + 1];
+    struct {
+	int seen;                // true if dwarf has seen him
+	loc_t loc;               // location of dwarves, initially hard-wired in
+	loc_t oldloc;            // prior loc of each dwarf, initially garbage
+    } dwarves[NDWARVES + 1];
+    struct {
+#ifdef FOUNDBOOL
+	bool found;	         // has the location of this object bween found?
+#endif
+	loc_t fixed;             // fixed location of object (if not IS_FREE)
+        int prop;                // object state */
+	loc_t place;             // location of object
+    } objects[NOBJECTS + 1];
+    struct { 
+	bool used;               // hints[i].used = true iff hint i has been used.
+#ifndef FOUNDBOOL
+	int lc;                 // hints[i].lc = show int at LOC with cond bit i
+#else
+	int lc;                  // hints[i].lc = show int at LOC with cond bit i
+#endif
+    } hints[NHINTS];
     obj_t link[NOBJECTS * 2 + 1];// object-list links
-    loc_t place[NOBJECTS + 1];   // location of object
-    int hinted[NHINTS];          // hinted[i] = true iff hint i has been used.
-    int hintlc[NHINTS];          // hintlc[i] = how int at LOC with cond bit i
-    int prop[NOBJECTS + 1];      // object state array */
 };
 
 /*
@@ -200,6 +270,7 @@ struct settings_t {
     int argc;
     int optind;
     FILE *scriptfp;
+    int debug;
 };
 
 typedef struct {
@@ -218,7 +289,34 @@ typedef struct {
     command_state_t state;
 } command_t;
 
+/*
+ * Bump on save format change.
+ *
+ * Note: Verify that the tests run clean before bumping this, then rebuild the check
+ * files afterwards.  Otherwise you will get a spurious failure due to the old version
+ * having been generated into a check file.
+ */
+#define SAVE_VERSION	30
+
+/*
+ * Goes at start of file so saves can be identified by file(1) and the like.
+ */
+#define ADVENT_MAGIC	"open-adventure\n"
+
+/*
+ * If you change the first three members, the resume function may not properly
+ * reject saves from older versions. Later members can change, but bump the version
+ * when you do that.
+ */
+struct save_t {
+    char magic[sizeof(ADVENT_MAGIC)];
+    int32_t version;
+    int32_t canary;
+    struct game_t game;
+};
+
 extern struct game_t game;
+extern struct save_t save;
 extern struct settings_t settings;
 
 extern char *myreadline(const char *);
@@ -233,7 +331,7 @@ extern bool silent_yes_or_no(void);
 extern bool yes_or_no(const char*, const char*, const char*);
 extern void juggle(obj_t);
 extern void move(obj_t, loc_t);
-extern loc_t put(obj_t, int, int);
+extern void put(obj_t, loc_t, int);
 extern void carry(obj_t, loc_t);
 extern void drop(obj_t, loc_t);
 extern int atdwrf(loc_t);
@@ -243,7 +341,10 @@ extern void set_seed(int32_t);
 extern int32_t randrange(int32_t);
 extern int score(enum termination);
 extern void terminate(enum termination) __attribute__((noreturn));
-extern int savefile(FILE *, int32_t);
+extern int savefile(FILE *);
+#if defined ADVENT_AUTOSAVE
+extern void autosave(void);
+#endif
 extern int suspend(void);
 extern int resume(void);
 extern int restore(FILE *);
@@ -251,8 +352,7 @@ extern int initialise(void);
 extern phase_codes_t action(command_t);
 extern void state_change(obj_t, int);
 extern bool is_valid(struct game_t);
-
-void bug(enum bugtype, const char *) __attribute__((__noreturn__));
+extern void bug(enum bugtype, const char *) __attribute__((__noreturn__));
 
 /* represent an empty command word */
 static const command_word_t empty_command_word = {
diff --git a/advent.svg b/advent.svg
index 8f50e5e..02a0e1b 100644
--- a/advent.svg
+++ b/advent.svg
@@ -2,30 +2,8 @@
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
   "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 <!--
-Copyright © 2017 Dr. Tobias Quathamer <toddy@debian.org>
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-1. Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+SPDX-FileCopyrightText: 2017 Dr. Tobias Quathamer <toddy@debian.org>
+SPDX-License-Identifier: BSD-2-Clause
 -->
 <svg width="128" height="128" version="1.1"
   xmlns="http://www.w3.org/2000/svg">
diff --git a/adventure.yaml b/adventure.yaml
index 18780a3..8909914 100644
--- a/adventure.yaml
+++ b/adventure.yaml
@@ -1,3 +1,6 @@
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#
 # This YAML file gets processed into a collection of data structures and
 # variable initializers describing Colossal Cave.  It replaces an ad-hoc
 # text database shipped with Adventure versions up to 2.5.  The format
@@ -24,7 +27,7 @@
 #      long:         Long description, always shown on first encounter.
 #      short:        Short description. If none, use long description.
 #      maptag:       Tag for mapping, not used by the game itself.
-#                    Only used if the "short" property in !!null.
+#                    Only used if the "short" property is !!null.
 #      conditions:   A dictionary of attributes
 #        LIT		Light
 #        OILY		If FLUID flag is on: true for oil, false for water
@@ -112,12 +115,12 @@
 # message when the message is printed.  These sequences are:
 #       %d = an integer
 #       %s = an ASCII string
-#	%S = The letter 's' or nothing (if a previous %d value is exactly 1)
+#	%S = the letter 's' or nothing (if a previous %d value is exactly 1)
 #	%V = substitute program version string
 #
-# Copyright (c) 2017 by Eric S. Raymond
-# SPDX-License-Identifier: BSD-2-clause
 
+# Motion names of the form MOT_* are not explicitly referenced in the
+# locations YAML, but usually get compiled into generated C.
 motions: !!omap
 - MOT_0:
     words: !!null
@@ -2105,7 +2108,7 @@ locations: !!omap
     ]
 - LOC_LIMESTONE:
     description:
-      long:
+      long: |-
           You are walking along a gently sloping north/south passage lined with
           oddly shaped limestone formations.
       short: 'You''re in limestone passage.'
@@ -2753,7 +2756,7 @@ locations: !!omap
           You are on a small ledge at the top of a nearly vertical cliff.
           There is a low crawl leading off to the northeast.
       short: 'You''re at top of cliff.'
-      maptag: 'Cliftop'
+      maptag: 'Clifftop'
     conditions: {DEEP: true}
     travel: [
       {verbs: [CLIMB, DOWN], action: [goto, LOC_CLIFFACE]},
@@ -3013,6 +3016,7 @@ arbitrary_messages:  !!omap
       black smoke.
 - SHELL_IMPERVIOUS: 'The shell is very strong and is impervious to attack.'
 - START_OVER: 'What''s the matter, can''t you read?  Now you''d best start over.'
+- WELL_POINTLESS: 'Well, that was remarkably pointless!'
 - DRAGON_SCALES: 'The axe bounces harmlessly off the dragon''s thick scales.'
 - NASTY_DRAGON: 'The dragon looks rather nasty.  You''d best not try to get by.'
 - BIRD_BURNT: |-
@@ -3171,6 +3175,7 @@ arbitrary_messages:  !!omap
     To achieve the next higher rating would be a neat trick!
     Congratulations!!
 - OFF_SCALE: 'You just went off my scale!!'
+- SAVERESUME_DISABLED: 'Save and resume are disabled.'
 - RESUME_HELP: 'To resume your Adventure, start a new game and then say "RESUME".'
 # This message is not currently used
 #- TABLE_SPACE: |-
@@ -3181,18 +3186,18 @@ arbitrary_messages:  !!omap
 #    %d of %d "random" messages   %d of %d "class" messages
 #    %d of %d hints               %d of %d turn thresholds'
 - RESUME_ABANDON: 'To resume an earlier Adventure, you must abandon the current one.'
+- BAD_SAVE: 'Oops, that does not look like a valid save file.'
 - VERSION_SKEW: |-
     I'm sorry, but that Adventure was begun using Version %d.%d of the
     save file format, and this program uses Version %d.%d.  You must find an instance
     using that other version in order to resume that Adventure.
-# This message is not currently used
-#- SAVE_TAMPERING: |-
-#    A dark fog creeps in to surround you.  From somewhere in the fog you
-#    hear a stern voice.  "This Adventure has been tampered with!  You have
-#    been dabbling in magic, knowing not the havoc you might cause thereby.
-#    Leave at once, before you do irrevocable harm!"  The fog thickens,
-#    until at last you can see nothing at all.  Your vision then clears,
-#    and you find yourself back in The Real World.
+- SAVE_TAMPERING: |-
+    A dark fog creeps in to surround you.  From somewhere in the fog you
+    hear a stern voice.  "This Adventure has been tampered with!  You have
+    been dabbling in magic, knowing not the havoc you might cause thereby.
+    Leave at once, before you do irrevocable harm!"  The fog thickens,
+    until at last you can see nothing at all.  Your vision then clears,
+    and you find yourself back in The Real World.
 - TWIST_TURN: |-
     Sorry, but the path twisted and turned so much that I can't figure
     out which way to go to get back.
@@ -3225,10 +3230,10 @@ classes:
   message: 'All of Adventuredom gives tribute to you, Adventurer Grandmaster!'
 - threshold: 9999
   message: |-
-    'Adventuredom stands in awe -- you have now joined the ranks of the
+    Adventuredom stands in awe -- you have now joined the ranks of the
            W O R L D   C H A M P I O N   A D V E N T U R E R S !
     It may interest you to know that the Dungeon-Master himself has, to
-    my knowledge, never achieved this threshold in fewer than 330 turns.'
+    my knowledge, never achieved this threshold in fewer than 330 turns.
 
 turn_thresholds:
 - threshold: 350
@@ -4142,7 +4147,7 @@ actions: !!omap
     message: |-
       Mist is a white vapor, usually water, seen from time to time in
       caverns.  It can be found anywhere but is frequently a sign of a deep
-      pit leading down to water.'
+      pit leading down to water.
     words: ['mist']
     noaction: true
 - FBOMB:
diff --git a/cheat.c b/cheat.c
index 92500e4..1a415b7 100644
--- a/cheat.c
+++ b/cheat.c
@@ -1,12 +1,12 @@
 /*
  * 'cheat' is a tool for generating save game files to test states that ought
  * not happen. It leverages chunks of advent, mostly initialize() and
- * savefile(), so we know we're always outputing save files that advent
+ * savefile(), so we know we're always outputting save files that advent
  * can import.
  *
- * Copyright (c) 1977, 2005 by Will Crowther and Don Woods
- * Copyright (c) 2017 by Eric S. Raymond
- * SPDX-License-Identifier: BSD-2-clause
+ * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods
+ * SPDX-FileCopyrightText: 2017 by Eric S. Raymond
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <getopt.h>
 #include <stdlib.h>
@@ -19,7 +19,6 @@ int main(int argc, char *argv[])
 {
     int ch;
     char *savefilename = NULL;
-    int version = 0;
     FILE *fp = NULL;
 
     // Initialize game variables
@@ -59,8 +58,8 @@ int main(int argc, char *argv[])
             printf("cheat: game.turns = %d\n", game.turns);
             break;
         case 'v':
-            version = atoi(optarg);
-            printf("cheat: version = %d\n", version);
+            save.version = atoi(optarg);
+            printf("cheat: version = %d\n", save.version);
             break;
         case 'o':
             savefilename = optarg;
@@ -89,7 +88,7 @@ int main(int argc, char *argv[])
         exit(EXIT_FAILURE);
     }
 
-    savefile(fp, version);
+    savefile(fp);
 
     fclose(fp);
 
diff --git a/debian/changelog b/debian/changelog
index a0a9774..2a4b4d2 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+open-adventure (1.16-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Sun, 11 Jun 2023 03:58:14 -0000
+
 open-adventure (1.12-1) unstable; urgency=medium
 
   * New upstream version 1.12
diff --git a/hints.adoc b/hints.adoc
index 1d2b092..c77afee 100644
--- a/hints.adoc
+++ b/hints.adoc
@@ -1,4 +1,6 @@
 = Non-spoiler hints =
+// SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+// SPDX-License-Identifier: CC-BY-4.0
 
 Say the words you see.  They can have interesting effects.
 
diff --git a/history.adoc b/history.adoc
index 6f86fac..1e4028c 100644
--- a/history.adoc
+++ b/history.adoc
@@ -1,5 +1,7 @@
 = A brief history of Colossal Cave Adventure =
 by Eric S. Raymond
+// SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+// SPDX-License-Identifier: CC-BY-4.0
 
 Adventure is the fons et origo of all later dungeon-crawling computer
 games, the granddaddy of interactive fiction, and one of the hallowed
@@ -163,9 +165,9 @@ even as primitive as Adventure's.
 
 - [[[SN]]]
   http://www.digitalhumanities.org/dhq/vol/1/2/000009/000009.html[Digital
-  Humanties Quarterly]
+  Humanities Quarterly]
 
-- [[[DND]]] https://en.wikipedia.org/wiki/Dnd_(video_game)[dnd (ivdeo game)]
+- [[[DND]]] https://en.wikipedia.org/wiki/Dnd_(video_game)[dnd (video game)]
 
 - [[[WUMPUS]]] https://en.wikipedia.org/wiki/Hunt_the_Wumpus[Hunt The Wumpus]
 
diff --git a/init.c b/init.c
index 9333df3..9104a59 100644
--- a/init.c
+++ b/init.c
@@ -1,9 +1,9 @@
 /*
  * Initialisation
  *
- * Copyright (c) 1977, 2005 by Will Crowther and Don Woods
- * Copyright (c) 2017 by Eric S. Raymond
- * SPDX-License-Identifier: BSD-2-clause
+ * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods
+ * SPDX-FileCopyrightText: 2017 by Eric S. Raymond
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <unistd.h>
@@ -21,17 +21,17 @@ struct settings_t settings = {
 };
 
 struct game_t game = {
-    .dloc[1] = LOC_KINGHALL,
-    .dloc[2] = LOC_WESTBANK,
-    .dloc[3] = LOC_Y2,
-    .dloc[4] = LOC_ALIKE3,
-    .dloc[5] = LOC_COMPLEX,
+    .dwarves[1].loc = LOC_KINGHALL,
+    .dwarves[2].loc = LOC_WESTBANK,
+    .dwarves[3].loc = LOC_Y2,
+    .dwarves[4].loc = LOC_ALIKE3,
+    .dwarves[5].loc = LOC_COMPLEX,
 
     /*  Sixth dwarf is special (the pirate).  He always starts at his
      *  chest's eventual location inside the maze. This loc is saved
      *  in chloc for ref. The dead end in the other maze has its
      *  loc stored in chloc2. */
-    .dloc[6] = LOC_MAZEEND12,
+    .dwarves[6].loc = LOC_MAZEEND12,
     .chloc   = LOC_MAZEEND12,
     .chloc2  = LOC_DEADEND13,
     .abbnum  = 5,
@@ -53,19 +53,18 @@ int initialise(void)
     set_seed(seedval);
 
     for (int i = 1; i <= NOBJECTS; i++) {
-        game.place[i] = LOC_NOWHERE;
+        game.objects[i].place = LOC_NOWHERE;
     }
 
     for (int i = 1; i <= NLOCATIONS; i++) {
-        if (!(locations[i].description.big == 0 ||
-              tkey[i] == 0)) {
+        if (!(locations[i].description.big == 0 || tkey[i] == 0)) {
             int k = tkey[i];
             if (travel[k].motion == HERE)
                 conditions[i] |= (1 << COND_FORCED);
         }
     }
 
-    /*  Set up the game.atloc and game.link arrays.
+    /*  Set up the game.locs atloc and game.link arrays.
      *  We'll use the DROP subroutine, which prefaces new objects on the
      *  lists.  Since we want things in the other order, we'll run the
      *  loop backwards.  If the object is in two locs, we drop it twice.
@@ -80,22 +79,23 @@ int initialise(void)
 
     for (int i = 1; i <= NOBJECTS; i++) {
         int k = NOBJECTS + 1 - i;
-        game.fixed[k] = objects[k].fixd;
+        game.objects[k].fixed = objects[k].fixd;
         if (objects[k].plac != 0 && objects[k].fixd <= 0)
             drop(k, objects[k].plac);
     }
 
-    /*  Treasure props are initially -1, and are set to 0 the first time
-     *  they are described.  game.tally keeps track of how many are
-     *  not yet found, so we know when to close the cave. */
+    /*  Treasure props are initially STATE_NOTFOUND, and are set to
+     *  STATE_FOUND the first time they are described.  game.tally
+     *  keeps track of how many are not yet found, so we know when to
+     *  close the cave. */
     for (int treasure = 1; treasure <= NOBJECTS; treasure++) {
         if (objects[treasure].is_treasure) {
+            ++game.tally;
             if (objects[treasure].inventory != 0)
-                game.prop[treasure] = STATE_NOTFOUND;
-            game.tally = game.tally - game.prop[treasure];
+                PROP_SET_NOT_FOUND(treasure);
         }
     }
-    game.conds = setbit(11);
+    game.conds = setbit(COND_HBASE);
 
     return seedval;
 }
diff --git a/main.c b/main.c
index b3a8f95..cbaf92c 100644
--- a/main.c
+++ b/main.c
@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 1977, 2005 by Will Crowther and Don Woods
- * Copyright (c) 2017 by Eric S. Raymond
- * SPDX-License-Identifier: BSD-2-clause
+ * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods
+ * SPDX-FileCopyrightText: 2017 by Eric S. Raymond
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdlib.h>
@@ -18,6 +18,18 @@
 
 #define DIM(a) (sizeof(a)/sizeof(a[0]))
 
+#if defined ADVENT_AUTOSAVE
+static FILE* autosave_fp;
+void autosave(void)
+{
+    if (autosave_fp != NULL) {
+        rewind(autosave_fp);
+        savefile(autosave_fp);
+        fflush(autosave_fp);
+    }
+}
+#endif
+
 // LCOV_EXCL_START
 // exclude from coverage analysis because it requires interactivity to test
 static void sig_handler(int signo)
@@ -26,126 +38,30 @@ static void sig_handler(int signo)
         if (settings.logfp != NULL)
             fflush(settings.logfp);
     }
-    exit(EXIT_FAILURE);
-}
-// LCOV_EXCL_STOP
 
-/*
- * MAIN PROGRAM
- *
- *  Adventure (rev 2: 20 treasures)
- *  History: Original idea & 5-treasure version (adventures) by Willie Crowther
- *           15-treasure version (adventure) by Don Woods, April-June 1977
- *           20-treasure version (rev 2) by Don Woods, August 1978
- *		Errata fixed: 78/12/25
- *	     Revived 2017 as Open Adventure.
- */
-
-static bool do_command(void);
-static bool do_move(void);
-
-int main(int argc, char *argv[])
-{
-    int ch;
-
-    /*  Options. */
-
-#ifndef ADVENT_NOSAVE
-    const char* opts = "l:or:";
-    const char* usage = "Usage: %s [-l logfilename] [-o] [-r restorefilename] [script...]\n";
-    FILE *rfp = NULL;
-#else
-    const char* opts = "l:o";
-    const char* usage = "Usage: %s [-l logfilename] [-o] [script...]\n";
-#endif
-    while ((ch = getopt(argc, argv, opts)) != EOF) {
-        switch (ch) {
-        case 'l':
-            settings.logfp = fopen(optarg, "w");
-            if (settings.logfp == NULL)
-                fprintf(stderr,
-                        "advent: can't open logfile %s for write\n",
-                        optarg);
-            signal(SIGINT, sig_handler);
-            break;
-        case 'o':
-            settings.oldstyle = true;
-            settings.prompt = false;
-            break;
-#ifndef ADVENT_NOSAVE
-        case 'r':
-            rfp = fopen(optarg, "r");
-            if (rfp == NULL)
-                fprintf(stderr,
-                        "advent: can't open save file %s for read\n",
-                        optarg);
-            break;
+#if defined ADVENT_AUTOSAVE
+    if (signo == SIGHUP || signo == SIGTERM)
+        autosave();
 #endif
-        default:
-            fprintf(stderr,
-                    usage, argv[0]);
-            fprintf(stderr,
-                    "        -l create a log file of your game named as specified'\n");
-            fprintf(stderr,
-                    "        -o 'oldstyle' (no prompt, no command editing, displays 'Initialising...')\n");
-#ifndef ADVENT_NOSAVE
-            fprintf(stderr,
-                    "        -r restore from specified saved game file\n");
-#endif
-            exit(EXIT_FAILURE);
-            break;
-        }
-    }
-
-    /* copy inncation line part after switches */
-    settings.argc = argc - optind;
-    settings.argv = argv + optind;
-    settings.optind = 0;
-
-    /*  Initialize game variables */
-    int seedval = initialise();
-
-#ifndef ADVENT_NOSAVE
-    if (!rfp) {
-        game.novice = yes_or_no(arbitrary_messages[WELCOME_YOU], arbitrary_messages[CAVE_NEARBY], arbitrary_messages[NO_MESSAGE]);
-        if (game.novice)
-            game.limit = NOVICELIMIT;
-    } else {
-        restore(rfp);
-    }
-#else
-    game.novice = yes_or_no(arbitrary_messages[WELCOME_YOU], arbitrary_messages[CAVE_NEARBY], arbitrary_messages[NO_MESSAGE]);
-    if (game.novice)
-        game.limit = NOVICELIMIT;
-#endif
-
-    if (settings.logfp)
-        fprintf(settings.logfp, "seed %d\n", seedval);
-
-    /* interpret commands until EOF or interrupt */
-    for (;;) {
-        // if we're supposed to move, move
-        if (!do_move())
-            continue;
-
-        // get command
-        if (!do_command())
-            break;
-    }
-    /* show score and exit */
-    terminate(quitgame);
+    exit(EXIT_FAILURE);
 }
+// LCOV_EXCL_STOP
 
 char *myreadline(const char *prompt)
 {
     /*
-     * This function isbn't required for gameplay, readline() straight
-     * up would suffice for tat.  It's where we interpret command-line
+     * This function isn't required for gameplay, readline() straight
+     * up would suffice for that.  It's where we interpret command-line
      * logfiles for testing purposes.
      */
     /* Normal case - no script arguments */
-    if (settings.argc == 0)
-        return readline(prompt);
+    if (settings.argc == 0) {
+	char *ln = readline(prompt);
+	if (ln == NULL) {
+	    fputs(prompt, stdout);
+	}
+        return ln;
+    }
 
     char *buf = malloc(LINESIZE + 1);
     for (;;) {
@@ -171,9 +87,9 @@ char *myreadline(const char *prompt)
         } else {
             char *ln = fgets(buf, LINESIZE, settings.scriptfp);
             if (ln != NULL) {
-                fputs(PROMPT, stdout);
+		fputs(prompt, stdout);
                 fputs(ln, stdout);
-                return ln;
+		return ln;
             }
         }
     }
@@ -188,71 +104,71 @@ static void checkhints(void)
 {
     if (conditions[game.loc] >= game.conds) {
         for (int hint = 0; hint < NHINTS; hint++) {
-            if (game.hinted[hint])
+            if (game.hints[hint].used)
                 continue;
             if (!CNDBIT(game.loc, hint + 1 + COND_HBASE))
-                game.hintlc[hint] = -1;
-            ++game.hintlc[hint];
+                game.hints[hint].lc = -1;
+            ++game.hints[hint].lc;
             /*  Come here if he's been int enough at required loc(s) for some
              *  unused hint. */
-            if (game.hintlc[hint] >= hints[hint].turns) {
+            if (game.hints[hint].lc >= hints[hint].turns) {
                 int i;
 
                 switch (hint) {
                 case 0:
                     /* cave */
-                    if (game.prop[GRATE] == GRATE_CLOSED && !HERE(KEYS))
+                    if (game.objects[GRATE].prop == GRATE_CLOSED && !HERE(KEYS))
                         break;
-                    game.hintlc[hint] = 0;
+                    game.hints[hint].lc = 0;
                     return;
                 case 1:	/* bird */
-                    if (game.place[BIRD] == game.loc && TOTING(ROD) && game.oldobj == BIRD)
+                    if (game.objects[BIRD].place == game.loc && TOTING(ROD) && game.oldobj == BIRD)
                         break;
                     return;
                 case 2:	/* snake */
                     if (HERE(SNAKE) && !HERE(BIRD))
                         break;
-                    game.hintlc[hint] = 0;
+                    game.hints[hint].lc = 0;
                     return;
                 case 3:	/* maze */
-                    if (game.atloc[game.loc] == NO_OBJECT &&
-                        game.atloc[game.oldloc] == NO_OBJECT &&
-                        game.atloc[game.oldlc2] == NO_OBJECT &&
+                    if (game.locs[game.loc].atloc == NO_OBJECT &&
+                        game.locs[game.oldloc].atloc == NO_OBJECT &&
+                        game.locs[game.oldlc2].atloc == NO_OBJECT &&
                         game.holdng > 1)
                         break;
-                    game.hintlc[hint] = 0;
+                    game.hints[hint].lc = 0;
                     return;
                 case 4:	/* dark */
-                    if (game.prop[EMERALD] != STATE_NOTFOUND && game.prop[PYRAMID] == STATE_NOTFOUND)
+                    if (!PROP_IS_NOTFOUND(EMERALD) && PROP_IS_NOTFOUND(PYRAMID))
                         break;
-                    game.hintlc[hint] = 0;
+                    game.hints[hint].lc = 0;
                     return;
                 case 5:	/* witt */
                     break;
                 case 6:	/* urn */
                     if (game.dflag == 0)
                         break;
-                    game.hintlc[hint] = 0;
+                    game.hints[hint].lc = 0;
                     return;
                 case 7:	/* woods */
-                    if (game.atloc[game.loc] == NO_OBJECT &&
-                        game.atloc[game.oldloc] == NO_OBJECT &&
-                        game.atloc[game.oldlc2] == NO_OBJECT)
+                    if (game.locs[game.loc].atloc == NO_OBJECT &&
+                        game.locs[game.oldloc].atloc == NO_OBJECT &&
+                        game.locs[game.oldlc2].atloc == NO_OBJECT)
                         break;
                     return;
                 case 8:	/* ogre */
                     i = atdwrf(game.loc);
                     if (i < 0) {
-                        game.hintlc[hint] = 0;
+                        game.hints[hint].lc = 0;
                         return;
                     }
                     if (HERE(OGRE) && i == 0)
                         break;
                     return;
                 case 9:	/* jade */
-                    if (game.tally == 1 && game.prop[JADE] < 0)
+                    if (game.tally == 1 && PROP_IS_STASHED_OR_UNSEEN(JADE))
                         break;
-                    game.hintlc[hint] = 0;
+                    game.hints[hint].lc = 0;
                     return;
                 default: // LCOV_EXCL_LINE
                     // Should never happen
@@ -260,12 +176,12 @@ static void checkhints(void)
                 }
 
                 /* Fall through to hint display */
-                game.hintlc[hint] = 0;
+                game.hints[hint].lc = 0;
                 if (!yes_or_no(hints[hint].question, arbitrary_messages[NO_MESSAGE], arbitrary_messages[OK_MAN]))
                     return;
                 rspeak(HINT_COST, hints[hint].penalty, hints[hint].penalty);
-                game.hinted[hint] = yes_or_no(arbitrary_messages[WANT_HINT], hints[hint].hint, arbitrary_messages[OK_MAN]);
-                if (game.hinted[hint] && game.limit > WARNTIME)
+                game.hints[hint].used = yes_or_no(arbitrary_messages[WANT_HINT], hints[hint].hint, arbitrary_messages[OK_MAN]);
+                if (game.hints[hint].used && game.limit > WARNTIME)
                     game.limit += WARNTIME * hints[hint].penalty;
             }
         }
@@ -280,11 +196,10 @@ static bool spotted_by_pirate(int i)
     /*  The pirate's spotted him.  Pirate leaves him alone once we've
      *  found chest.  K counts if a treasure is here.  If not, and
      *  tally=1 for an unseen chest, let the pirate be spotted.  Note
-     *  that game.place[CHEST] = LOC_NOWHERE might mean that he's thrown
+     *  that game.objexts,place[CHEST] = LOC_NOWHERE might mean that he's thrown
      *  it to the troll, but in that case he's seen the chest
-     *  (game.prop[CHEST] == STATE_FOUND). */
-    if (game.loc == game.chloc ||
-        game.prop[CHEST] != STATE_NOTFOUND)
+     *  PROP_IS_FOUND(CHEST) == true. */
+    if (game.loc == game.chloc || !PROP_IS_NOTFOUND(CHEST))
         return true;
     int snarfed = 0;
     bool movechest = false, robplayer = false;
@@ -297,8 +212,7 @@ static bool spotted_by_pirate(int i)
                                     game.loc == objects[EMERALD].plac)) {
             continue;
         }
-        if (TOTING(treasure) ||
-            HERE(treasure))
+        if (TOTING(treasure) || HERE(treasure))
             ++snarfed;
         if (TOTING(treasure)) {
             movechest = true;
@@ -306,7 +220,7 @@ static bool spotted_by_pirate(int i)
         }
     }
     /* Force chest placement before player finds last treasure */
-    if (game.tally == 1 && snarfed == 0 && game.place[CHEST] == LOC_NOWHERE && HERE(LAMP) && game.prop[LAMP] == LAMP_BRIGHT) {
+    if (game.tally == 1 && snarfed == 0 && game.objects[CHEST].place == LOC_NOWHERE && HERE(LAMP) && game.objects[LAMP].prop == LAMP_BRIGHT) {
         rspeak(PIRATE_SPOTTED);
         movechest = true;
     }
@@ -315,13 +229,13 @@ static bool spotted_by_pirate(int i)
     if (movechest) {
         move(CHEST, game.chloc);
         move(MESSAG, game.chloc2);
-        game.dloc[PIRATE] = game.chloc;
-        game.odloc[PIRATE] = game.chloc;
-        game.dseen[PIRATE] = false;
+        game.dwarves[PIRATE].loc = game.chloc;
+        game.dwarves[PIRATE].oldloc = game.chloc;
+        game.dwarves[PIRATE].seen = false;
     } else {
         /* You might get a hint of the pirate's presence even if the
          * chest doesn't move... */
-        if (game.odloc[PIRATE] != game.dloc[PIRATE] && PCT(20))
+        if (game.dwarves[PIRATE].oldloc != game.dwarves[PIRATE].loc && PCT(20))
             rspeak(PIRATE_RUSTLES);
     }
     if (robplayer) {
@@ -331,7 +245,7 @@ static bool spotted_by_pirate(int i)
                 continue;
             if (!(treasure == PYRAMID && (game.loc == objects[PYRAMID].plac ||
                                           game.loc == objects[EMERALD].plac))) {
-                if (AT(treasure) && game.fixed[treasure] == IS_FREE)
+                if (AT(treasure) && game.objects[treasure].fixed == IS_FREE)
                     carry(treasure, game.loc);
                 if (TOTING(treasure))
                     drop(treasure, game.chloc);
@@ -360,9 +274,7 @@ static bool dwarfmove(void)
      *  steal return toll, and dwarves can't meet the bear.  Also
      *  means dwarves won't follow him into dead end in maze, but
      *  c'est la vie.  They'll wait for him outside the dead end. */
-    if (game.loc == LOC_NOWHERE ||
-        FORCED(game.loc) ||
-        CNDBIT(game.newloc, COND_NOARRR))
+    if (game.loc == LOC_NOWHERE || FORCED(game.loc) || CNDBIT(game.newloc, COND_NOARRR))
         return true;
 
     /* Dwarf activity level ratchets up */
@@ -377,22 +289,21 @@ static bool dwarfmove(void)
      *  replace him with the alternate. */
     if (game.dflag == 1) {
         if (!INDEEP(game.loc) ||
-            (PCT(95) && (!CNDBIT(game.loc, COND_NOBACK) ||
-                         PCT(85))))
+            (PCT(95) && (!CNDBIT(game.loc, COND_NOBACK) || PCT(85))))
             return true;
         game.dflag = 2;
         for (int i = 1; i <= 2; i++) {
             int j = 1 + randrange(NDWARVES - 1);
             if (PCT(50))
-                game.dloc[j] = 0;
+                game.dwarves[j].loc = 0;
         }
 
         /* Alternate initial loc for dwarf, in case one of them
         *  starts out on top of the adventurer. */
         for (int i = 1; i <= NDWARVES - 1; i++) {
-            if (game.dloc[i] == game.loc)
-                game.dloc[i] = DALTLC; //
-            game.odloc[i] = game.dloc[i];
+            if (game.dwarves[i].loc == game.loc)
+                game.dwarves[i].loc = DALTLC; //
+            game.dwarves[i].oldloc = game.dwarves[i].loc;
         }
         rspeak(DWARF_RAN);
         drop(AXE, game.loc);
@@ -409,11 +320,11 @@ static bool dwarfmove(void)
     attack = 0;
     stick = 0;
     for (int i = 1; i <= NDWARVES; i++) {
-        if (game.dloc[i] == 0)
+        if (game.dwarves[i].loc == 0)
             continue;
         /*  Fill tk array with all the places this dwarf might go. */
         unsigned int j = 1;
-        kk = tkey[game.dloc[i]];
+        kk = tkey[game.dwarves[i].loc];
         if (kk != 0)
             do {
                 enum desttype_t desttype = travel[kk].desttype;
@@ -423,14 +334,14 @@ static bool dwarfmove(void)
                     continue;
                 else if (!INDEEP(game.newloc))
                     continue;
-                else if (game.newloc == game.odloc[i])
+                else if (game.newloc == game.dwarves[i].oldloc)
                     continue;
                 else if (j > 1 && game.newloc == tk[j - 1])
                     continue;
                 else if (j >= DIM(tk) - 1)
                     /* This can't actually happen. */
                     continue; // LCOV_EXCL_LINE
-                else if (game.newloc == game.dloc[i])
+                else if (game.newloc == game.dwarves[i].loc)
                     continue;
                 else if (FORCED(game.newloc))
                     continue;
@@ -441,25 +352,25 @@ static bool dwarfmove(void)
                 tk[j++] = game.newloc;
             } while
             (!travel[kk++].stop);
-        tk[j] = game.odloc[i];
+        tk[j] = game.dwarves[i].oldloc;
         if (j >= 2)
             --j;
         j = 1 + randrange(j);
-        game.odloc[i] = game.dloc[i];
-        game.dloc[i] = tk[j];
-        game.dseen[i] = (game.dseen[i] && INDEEP(game.loc)) ||
-                        (game.dloc[i] == game.loc ||
-                         game.odloc[i] == game.loc);
-        if (!game.dseen[i])
+        game.dwarves[i].oldloc = game.dwarves[i].loc;
+        game.dwarves[i].loc = tk[j];
+        game.dwarves[i].seen = (game.dwarves[i].seen && INDEEP(game.loc)) ||
+                        (game.dwarves[i].loc == game.loc ||
+                         game.dwarves[i].oldloc == game.loc);
+        if (!game.dwarves[i].seen)
             continue;
-        game.dloc[i] = game.loc;
+        game.dwarves[i].loc = game.loc;
         if (spotted_by_pirate(i))
             continue;
         /* This threatening little dwarf is in the room with him! */
         ++game.dtotal;
-        if (game.odloc[i] == game.dloc[i]) {
+        if (game.dwarves[i].oldloc == game.dwarves[i].loc) {
             ++attack;
-            if (game.knfloc >= 0)
+            if (game.knfloc >= LOC_NOWHERE)
                 game.knfloc = game.loc;
             if (randrange(1000) < 95 * (game.dflag - 2))
                 ++stick;
@@ -528,9 +439,9 @@ static void croak(void)
         /* If player wishes to continue, we empty the liquids in the
          * user's inventory, turn off the lamp, and drop all items
          * where he died. */
-        game.place[WATER] = game.place[OIL] = LOC_NOWHERE;
+        game.objects[WATER].place = game.objects[OIL].place = LOC_NOWHERE;
         if (TOTING(LAMP))
-            game.prop[LAMP] = LAMP_DARK;
+            game.objects[LAMP].prop = LAMP_DARK;
         for (int j = 1; j <= NOBJECTS; j++) {
             int i = NOBJECTS + 1 - j;
             if (TOTING(i)) {
@@ -547,8 +458,7 @@ static void describe_location(void)
 {
     const char* msg = locations[game.loc].description.small;
 
-    if (MOD(game.abbrev[game.loc], game.abbnum) == 0 ||
-        msg == NO_MESSAGE)
+    if (MOD(game.locs[game.loc].abbrev, game.abbnum) == 0 || msg == NO_MESSAGE)
         msg = locations[game.loc].description.big;
 
     if (!FORCED(game.loc) && DARK(game.loc)) {
@@ -641,7 +551,7 @@ static void playermove(int motion)
             rspeak(NO_MORE_DETAIL);
         ++game.detail;
         game.wzdark = false;
-        game.abbrev[game.loc] = 0;
+        game.locs[game.loc].abbrev = 0;
         return;
     } else if (motion == CAVE) {
         /*  Cave.  Different messages depending on whether above ground. */
@@ -656,8 +566,7 @@ static void playermove(int motion)
     /* Look for a way to fulfil the motion verb passed in - travel_entry indexes
      * the beginning of the motion entries for here (game.loc). */
     for (;;) {
-        if ((travel[travel_entry].motion == HERE) ||
-            travel[travel_entry].motion == motion)
+        if ((travel[travel_entry].motion == HERE) || travel[travel_entry].motion == motion)
             break;
         if (travel[travel_entry].stop) {
             /*  Couldn't find an entry matching the motion word passed
@@ -711,17 +620,15 @@ static void playermove(int motion)
                 if (condtype < cond_not) {
                     /* YAML N and [pct N] conditionals */
                     if (condtype == cond_goto || condtype == cond_pct) {
-                        if (condarg1 == 0 ||
-                            PCT(condarg1))
+                        if (condarg1 == 0 || PCT(condarg1))
                             break;
                         /* else fall through */
                     }
                     /* YAML [with OBJ] clause */
-                    else if (TOTING(condarg1) ||
-                             (condtype == cond_with && AT(condarg1)))
+                    else if (TOTING(condarg1) || (condtype == cond_with && AT(condarg1)))
                         break;
                     /* else fall through to check [not OBJ STATE] */
-                } else if (game.prop[condarg1] != condarg2)
+                } else if (game.objects[condarg1].prop != condarg2)
                     break;
 
                 /* We arrive here on conditional failure.
@@ -757,8 +664,7 @@ static void playermove(int motion)
                     game.newloc = (game.loc == LOC_PLOVER)
                                   ? LOC_ALCOVE
                                   : LOC_PLOVER;
-                    if (game.holdng > 1 ||
-                        (game.holdng == 1 && !TOTING(EMERALD))) {
+                    if (game.holdng > 1 || (game.holdng == 1 && !TOTING(EMERALD))) {
                         game.newloc = game.loc;
                         rspeak(MUST_DROP);
                     }
@@ -792,9 +698,9 @@ static void playermove(int motion)
                      * (standard travel entries check for
                      * game.prop[TROLL]=TROLL_UNPAID.)  Special stuff
                      * for bear. */
-                    if (game.prop[TROLL] == TROLL_PAIDONCE) {
+                    if (game.objects[TROLL].prop == TROLL_PAIDONCE) {
                         pspeak(TROLL, look, true, TROLL_PAIDONCE);
-                        game.prop[TROLL] = TROLL_UNPAID;
+                        game.objects[TROLL].prop = TROLL_UNPAID;
                         DESTROY(TROLL2);
                         move(TROLL2 + NOBJECTS, IS_FREE);
                         move(TROLL, objects[TROLL].plac);
@@ -804,15 +710,15 @@ static void playermove(int motion)
                         return;
                     } else {
                         game.newloc = objects[TROLL].plac + objects[TROLL].fixd - game.loc;
-                        if (game.prop[TROLL] == TROLL_UNPAID)
-                            game.prop[TROLL] = TROLL_PAIDONCE;
+                        if (game.objects[TROLL].prop == TROLL_UNPAID)
+                            game.objects[TROLL].prop = TROLL_PAIDONCE;
                         if (!TOTING(BEAR))
                             return;
                         state_change(CHASM, BRIDGE_WRECKED);
-                        game.prop[TROLL] = TROLL_GONE;
+                        game.objects[TROLL].prop = TROLL_GONE;
                         drop(BEAR, game.newloc);
-                        game.fixed[BEAR] = IS_FIXED;
-                        game.prop[BEAR] = BEAR_DEAD;
+                        game.objects[BEAR].fixed = IS_FIXED;
+                        game.objects[BEAR].prop = BEAR_DEAD;
                         game.oldlc2 = game.newloc;
                         croak();
                         return;
@@ -830,7 +736,7 @@ static void playermove(int motion)
 static void lampcheck(void)
 /* Check game limit and lamp timers */
 {
-    if (game.prop[LAMP] == LAMP_BRIGHT)
+    if (game.objects[LAMP].prop == LAMP_BRIGHT)
         --game.limit;
 
     /*  Another way we can force an end to things is by having the
@@ -840,9 +746,9 @@ static void lampcheck(void)
      *  Second is for other cases of lamp dying.  Even after it goes
      *  out, he can explore outside for a while if desired. */
     if (game.limit <= WARNTIME) {
-        if (HERE(BATTERY) && game.prop[BATTERY] == FRESH_BATTERIES && HERE(LAMP)) {
+        if (HERE(BATTERY) && game.objects[BATTERY].prop == FRESH_BATTERIES && HERE(LAMP)) {
             rspeak(REPLACE_BATTERIES);
-            game.prop[BATTERY] = DEAD_BATTERIES;
+            game.objects[BATTERY].prop = DEAD_BATTERIES;
 #ifdef __unused__
             /* This code from the original game seems to have been faulty.
              * No tests ever passed the guard, and with the guard removed
@@ -855,9 +761,9 @@ static void lampcheck(void)
             game.lmwarn = false;
         } else if (!game.lmwarn && HERE(LAMP)) {
             game.lmwarn = true;
-            if (game.prop[BATTERY] == DEAD_BATTERIES)
+            if (game.objects[BATTERY].prop == DEAD_BATTERIES)
                 rspeak(MISSING_BATTERIES);
-            else if (game.place[BATTERY] == LOC_NOWHERE)
+            else if (game.objects[BATTERY].place == LOC_NOWHERE)
                 rspeak(LAMP_DIM);
             else
                 rspeak(GET_BATTERIES);
@@ -865,7 +771,7 @@ static void lampcheck(void)
     }
     if (game.limit == 0) {
         game.limit = -1;
-        game.prop[LAMP] = LAMP_DARK;
+        game.objects[LAMP].prop = LAMP_DARK;
         if (HERE(LAMP))
             rspeak(LAMP_OUT);
     }
@@ -877,19 +783,19 @@ static bool closecheck(void)
  *  chest, which may of course never show up).  Note that the
  *  treasures need not have been taken yet, just located.  Hence
  *  clock1 must be large enough to get out of the cave (it only ticks
- *  while inside the cave).  When it hits zero, we branch to 10000 to
- *  start closing the cave, and then sit back and wait for him to try
- *  to get out.  If he doesn't within clock2 turns, we close the cave;
- *  if he does try, we assume he panics, and give him a few additional
- *  turns to get frantic before we close.  When clock2 hits zero, we
- *  transport him into the final puzzle.  Note that the puzzle depends
- *  upon all sorts of random things.  For instance, there must be no
- *  water or oil, since there are beanstalks which we don't want to be
- *  able to water, since the code can't handle it.  Also, we can have
- *  no keys, since there is a grate (having moved the fixed object!)
- *  there separating him from all the treasures.  Most of these
- *  problems arise from the use of negative prop numbers to suppress
- *  the object descriptions until he's actually moved the objects. */
+ *  while inside the cave).  When it hits zero, we start closing the
+ *  cave, and then sit back and wait for him to try to get out.  If he
+ *  doesn't within clock2 turns, we close the cave; if he does try, we
+ *  assume he panics, and give him a few additional turns to get
+ *  frantic before we close.  When clock2 hits zero, we transport him
+ *  into the final puzzle.  Note that the puzzle depends upon all
+ *  sorts of random things.  For instance, there must be no water or
+ *  oil, since there are beanstalks which we don't want to be able to
+ *  water, since the code can't handle it.  Also, we can have no keys,
+ *  since there is a grate (having moved the fixed object!)  there
+ *  separating him from all the treasures.  Most of these problems
+ *  arise from the use of negative prop numbers to suppress the object
+ *  descriptions until he's actually moved the objects. */
 {
     /* If a turn threshold has been met, apply penalties and tell
      * the player about it. */
@@ -918,23 +824,23 @@ static bool closecheck(void)
      *  know the bivalve is an oyster.  *And*, the dwarves must
      *  have been activated, since we've found chest. */
     if (game.clock1 == 0) {
-        game.prop[GRATE] = GRATE_CLOSED;
-        game.prop[FISSURE] = UNBRIDGED;
+        game.objects[GRATE].prop = GRATE_CLOSED;
+        game.objects[FISSURE].prop = UNBRIDGED;
         for (int i = 1; i <= NDWARVES; i++) {
-            game.dseen[i] = false;
-            game.dloc[i] = LOC_NOWHERE;
+            game.dwarves[i].seen = false;
+            game.dwarves[i].loc = LOC_NOWHERE;
         }
         DESTROY(TROLL);
         move(TROLL + NOBJECTS, IS_FREE);
         move(TROLL2, objects[TROLL].plac);
         move(TROLL2 + NOBJECTS, objects[TROLL].fixd);
         juggle(CHASM);
-        if (game.prop[BEAR] != BEAR_DEAD)
+        if (game.objects[BEAR].prop != BEAR_DEAD)
             DESTROY(BEAR);
-        game.prop[CHAIN] = CHAIN_HEAP;
-        game.fixed[CHAIN] = IS_FREE;
-        game.prop[AXE] = AXE_HERE;
-        game.fixed[AXE] = IS_FREE;
+        game.objects[CHAIN].prop = CHAIN_HEAP;
+        game.objects[CHAIN].fixed = IS_FREE;
+        game.objects[AXE].prop = AXE_HERE;
+        game.objects[AXE].fixed = IS_FREE;
         rspeak(CAVE_CLOSING);
         game.clock1 = -1;
         game.closng = true;
@@ -953,32 +859,32 @@ static bool closecheck(void)
          *  objects come from known locations and/or states (e.g. the
          *  snake is known to have been destroyed and needn't be
          *  carried away from its old "place"), making the various
-         *  objects be handled differently.  We also drop all other
-         *  objects he might be carrying (lest he have some which
+         *  objects be handled differently.  We also drop all other 
+         *  objects he might be acrrying (lest he have some which
          *  could cause trouble, such as the keys).  We describe the
          *  flash of light and trundle back. */
-        game.prop[BOTTLE] = put(BOTTLE, LOC_NE, EMPTY_BOTTLE);
-        game.prop[PLANT] = put(PLANT, LOC_NE, PLANT_THIRSTY);
-        game.prop[OYSTER] = put(OYSTER, LOC_NE, STATE_FOUND);
-        game.prop[LAMP] = put(LAMP, LOC_NE, LAMP_DARK);
-        game.prop[ROD] = put(ROD, LOC_NE, STATE_FOUND);
-        game.prop[DWARF] = put(DWARF, LOC_NE, 0);
+        put(BOTTLE, LOC_NE, EMPTY_BOTTLE);
+        put(PLANT, LOC_NE, PLANT_THIRSTY);
+        put(OYSTER, LOC_NE, STATE_FOUND);
+        put(LAMP, LOC_NE, LAMP_DARK);
+        put(ROD, LOC_NE, STATE_FOUND);
+        put(DWARF, LOC_NE, STATE_FOUND);
         game.loc = LOC_NE;
         game.oldloc = LOC_NE;
         game.newloc = LOC_NE;
         /*  Leave the grate with normal (non-negative) property.
          *  Reuse sign. */
-        put(GRATE, LOC_SW, 0);
-        put(SIGN, LOC_SW, 0);
-        game.prop[SIGN] = ENDGAME_SIGN;
-        game.prop[SNAKE] = put(SNAKE, LOC_SW, SNAKE_CHASED);
-        game.prop[BIRD] = put(BIRD, LOC_SW, BIRD_CAGED);
-        game.prop[CAGE] = put(CAGE, LOC_SW, STATE_FOUND);
-        game.prop[ROD2] = put(ROD2, LOC_SW, STATE_FOUND);
-        game.prop[PILLOW] = put(PILLOW, LOC_SW, STATE_FOUND);
-
-        game.prop[MIRROR] = put(MIRROR, LOC_NE, STATE_FOUND);
-        game.fixed[MIRROR] = LOC_SW;
+        move(GRATE, LOC_SW);
+        move(SIGN, LOC_SW);
+        game.objects[SIGN].prop = ENDGAME_SIGN;
+        put(SNAKE, LOC_SW, SNAKE_CHASED);
+        put(BIRD, LOC_SW, BIRD_CAGED);
+        put(CAGE, LOC_SW, STATE_FOUND);
+        put(ROD2, LOC_SW, STATE_FOUND);
+        put(PILLOW, LOC_SW, STATE_FOUND);
+
+        put(MIRROR, LOC_NE, STATE_FOUND);
+        game.objects[MIRROR].fixed = LOC_SW;
 
         for (int i = 1; i <= NOBJECTS; i++) {
             if (TOTING(i))
@@ -1004,21 +910,27 @@ static void listobjects(void)
  *  get full score. */
 {
     if (!DARK(game.loc)) {
-        ++game.abbrev[game.loc];
-        for (int i = game.atloc[game.loc]; i != 0; i = game.link[i]) {
+        ++game.locs[game.loc].abbrev;
+        for (int i = game.locs[game.loc].atloc; i != 0; i = game.link[i]) {
             obj_t obj = i;
             if (obj > NOBJECTS)
                 obj = obj - NOBJECTS;
             if (obj == STEPS && TOTING(NUGGET))
                 continue;
-            if (game.prop[obj] < 0) {
+	    /* (ESR) Warning: it looks like you could get away with
+	     * running this code only on objects with the treasure
+	     * property set. Nope.  There is mystery here.
+	     */
+            if (PROP_IS_STASHED_OR_UNSEEN(obj)) {
                 if (game.closed)
                     continue;
-                game.prop[obj] = STATE_FOUND;
+                PROP_SET_FOUND(obj);
                 if (obj == RUG)
-                    game.prop[RUG] = RUG_DRAGON;
+                    game.objects[RUG].prop = RUG_DRAGON;
                 if (obj == CHAIN)
-                    game.prop[CHAIN] = CHAINING_BEAR;
+                    game.objects[CHAIN].prop = CHAINING_BEAR;
+		if (obj == EGGS)
+		    game.seenbigwords = true;
                 --game.tally;
                 /*  Note: There used to be a test here to see whether the
                  *  player had blown it so badly that he could never ever see
@@ -1035,9 +947,9 @@ static void listobjects(void)
                  *  gross blunder isn't likely to find everything else anyway
                  *  (so goes the rationalisation). */
             }
-            int kk = game.prop[obj];
+            int kk = game.objects[obj].prop;
             if (obj == STEPS)
-                kk = (game.loc == game.fixed[STEPS])
+                kk = (game.loc == game.objects[STEPS].fixed)
                      ? STEPS_UP
                      : STEPS_DOWN;
             pspeak(obj, look, true, kk);
@@ -1048,10 +960,10 @@ static void listobjects(void)
 static bool preprocess_command(command_t *command)
 /* Pre-processes a command input to see if we need to tease out a few specific cases:
  * - "enter water" or "enter stream":
- *   wierd specific case that gets the user wet, and then kicks us back to get another command
+ *   weird specific case that gets the user wet, and then kicks us back to get another command
  * - <object> <verb>:
  *   Irregular form of input, but should be allowed. We switch back to <verb> <object> form for
- *   furtherprocessing.
+ *   further processing.
  * - "grate":
  *   If in location with grate, we move to that grate. If we're in a number of other places,
  *   we move to the entrance.
@@ -1136,7 +1048,7 @@ static bool do_move(void)
      *  place) let him get out (and attacked). */
     if (game.newloc != game.loc && !FORCED(game.loc) && !CNDBIT(game.loc, COND_NOARRR)) {
         for (size_t i = 1; i <= NDWARVES - 1; i++) {
-            if (game.odloc[i] == game.newloc && game.dseen[i]) {
+            if (game.dwarves[i].oldloc == game.newloc && game.dwarves[i].seen) {
                 game.newloc = game.loc;
                 rspeak(DWARF_BLOCK);
                 break;
@@ -1153,7 +1065,7 @@ static bool do_move(void)
 
     /* The easiest way to get killed is to fall into a pit in
      * pitch darkness. */
-    if (!FORCED(game.loc) && DARK(game.loc) && game.wzdark && PCT(35)) { // FIXME: magic number
+    if (!FORCED(game.loc) && DARK(game.loc) && game.wzdark && PCT(PIT_KILL_PROB)) {
         rspeak(PIT_FALL);
         game.oldlc2 = game.loc;
         croak();
@@ -1163,7 +1075,7 @@ static bool do_move(void)
     return true;
 }
 
-static bool do_command()
+static bool do_command(void)
 /* Get and execute a command */
 {
     static command_t command;
@@ -1186,15 +1098,16 @@ static bool do_command()
         while (command.state <= GIVEN) {
 
             if (game.closed) {
-                /*  If closing time, check for any objects being toted with
-                 *  game.prop < 0 and stash them.  This way objects won't be
-                 *  described until they've been picked up and put down
-                 *  separate from their respective piles. */
-                if (game.prop[OYSTER] < 0 && TOTING(OYSTER))
+                /*  If closing time, check for any stashed objects
+                 *  being toted and unstash them.  This way objects
+                 *  won't be described until they've been picked up
+                 *  and put down separate from their respective
+                 *  piles. */
+                if ((PROP_IS_NOTFOUND(OYSTER) || PROP_IS_STASHED(OYSTER)) && TOTING(OYSTER))
                     pspeak(OYSTER, look, true, 1);
                 for (size_t i = 1; i <= NOBJECTS; i++) {
-                    if (TOTING(i) && game.prop[i] < 0)
-                        game.prop[i] = STASHED(i);
+                    if (TOTING(i) && (PROP_IS_NOTFOUND(i) || PROP_IS_STASHED(i)))
+                        game.objects[i].prop = PROP_STASHED(i);
                 }
             }
 
@@ -1214,6 +1127,12 @@ static bool do_command()
                 if (!get_command_input(&command))
                     return false;
 
+                /* Every input, check "foobar" flag. If zero, nothing's going
+                 * on. If pos, make neg. If neg, he skipped a word, so make it
+                 * zero.
+                 */
+                game.foobar = (game.foobar > WORD_EMPTY) ? -game.foobar : WORD_EMPTY;
+
                 ++game.turns;
                 preprocess_command(&command);
             }
@@ -1222,7 +1141,7 @@ static bool do_command()
             if (closecheck() )
                 return true;
 
-            /* loop until all words in command are procesed */
+            /* loop until all words in command are processed */
             while (command.state == PREPROCESSED ) {
                 command.state = PROCESSING;
 
@@ -1313,7 +1232,7 @@ static bool do_command()
                 default: // LCOV_EXCL_LINE
                     BUG(ACTION_RETURNED_PHASE_CODE_BEYOND_END_OF_SWITCH); // LCOV_EXCL_LINE
                 }
-            } /* while command has nob been fully processed */
+            } /* while command has not been fully processed */
         } /* while command is not yet given */
     } /* while command is not executed */
 
@@ -1321,4 +1240,137 @@ static bool do_command()
     return true;
 }
 
+/*
+ * MAIN PROGRAM
+ *
+ *  Adventure (rev 2: 20 treasures)
+ *  History: Original idea & 5-treasure version (adventures) by Willie Crowther
+ *           15-treasure version (adventure) by Don Woods, April-June 1977
+ *           20-treasure version (rev 2) by Don Woods, August 1978
+ *		Errata fixed: 78/12/25
+ *	     Revived 2017 as Open Adventure.
+ */
+
+int main(int argc, char *argv[])
+{
+    int ch;
+
+    /*  Options. */
+
+#if defined ADVENT_AUTOSAVE
+    const char* opts = "dl:oa:";
+    const char* usage = "Usage: %s [-l logfilename] [-o] [-a filename] [script...]\n";
+    FILE *rfp = NULL;
+    const char* autosave_filename = NULL;
+#elif !defined ADVENT_NOSAVE
+    const char* opts = "dl:or:";
+    const char* usage = "Usage: %s [-l logfilename] [-o] [-r restorefilename] [script...]\n";
+    FILE *rfp = NULL;
+#else
+    const char* opts = "dl:o";
+    const char* usage = "Usage: %s [-l logfilename] [-o] [script...]\n";
+#endif
+    while ((ch = getopt(argc, argv, opts)) != EOF) {
+        switch (ch) {
+	case 'd': // LCOV_EXCL_LINE
+	    settings.debug +=1; // LCOV_EXCL_LINE
+	    break; // LCOV_EXCL_LINE
+        case 'l':
+            settings.logfp = fopen(optarg, "w");
+            if (settings.logfp == NULL)
+                fprintf(stderr,
+                        "advent: can't open logfile %s for write\n",
+                        optarg);
+            signal(SIGINT, sig_handler);
+            break;
+        case 'o':
+            settings.oldstyle = true;
+            settings.prompt = false;
+            break;
+#ifdef ADVENT_AUTOSAVE
+        case 'a':
+            rfp = fopen(optarg, READ_MODE);
+            autosave_filename = optarg;
+            signal(SIGHUP, sig_handler);
+            signal(SIGTERM, sig_handler);
+            break;
+#elif !defined ADVENT_NOSAVE
+        case 'r':
+            rfp = fopen(optarg, "r");
+            if (rfp == NULL)
+                fprintf(stderr,
+                        "advent: can't open save file %s for read\n",
+                        optarg);
+            break;
+#endif
+        default:
+            fprintf(stderr,
+                    usage, argv[0]);
+            fprintf(stderr,
+                    "        -l create a log file of your game named as specified'\n");
+            fprintf(stderr,
+                    "        -o 'oldstyle' (no prompt, no command editing, displays 'Initialising...')\n");
+#if defined ADVENT_AUTOSAVE
+            fprintf(stderr,
+                    "        -a automatic save/restore from specified saved game file\n");
+#elif !defined ADVENT_NOSAVE
+            fprintf(stderr,
+                    "        -r restore from specified saved game file\n");
+#endif
+            exit(EXIT_FAILURE);
+            break;
+        }
+    }
+
+    /* copy invocation line part after switches */
+    settings.argc = argc - optind;
+    settings.argv = argv + optind;
+    settings.optind = 0;
+
+    /*  Initialize game variables */
+    int seedval = initialise();
+
+#if !defined ADVENT_NOSAVE
+    if (!rfp) {
+        game.novice = yes_or_no(arbitrary_messages[WELCOME_YOU], arbitrary_messages[CAVE_NEARBY], arbitrary_messages[NO_MESSAGE]);
+        if (game.novice)
+            game.limit = NOVICELIMIT;
+    } else {
+        restore(rfp);
+#if defined ADVENT_AUTOSAVE
+        score(scoregame);
+#endif
+    }
+#if defined ADVENT_AUTOSAVE
+    if (autosave_filename != NULL) {
+        if ((autosave_fp = fopen(autosave_filename, WRITE_MODE)) == NULL) {
+            perror(autosave_filename);
+            return EXIT_FAILURE;
+        }
+        autosave();
+    }
+#endif
+#else
+    game.novice = yes_or_no(arbitrary_messages[WELCOME_YOU], arbitrary_messages[CAVE_NEARBY], arbitrary_messages[NO_MESSAGE]);
+    if (game.novice)
+        game.limit = NOVICELIMIT;
+#endif
+
+    if (settings.logfp)
+        fprintf(settings.logfp, "seed %d\n", seedval);
+
+    /* interpret commands until EOF or interrupt */
+    for (;;) {
+        // if we're supposed to move, move
+        if (!do_move())
+            continue;
+
+        // get command
+        if (!do_command())
+            break;
+    }
+    /* show score and exit */
+    terminate(quitgame);
+}
+
 /* end */
diff --git a/make_dungeon.py b/make_dungeon.py
index f90ad32..bae97f2 100755
--- a/make_dungeon.py
+++ b/make_dungeon.py
@@ -1,4 +1,6 @@
 #!/usr/bin/env python3
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 """
 This is the open-adventure dungeon generator. It consumes a YAML description of
 the dungeon and outputs a dungeon.h and dungeon.c pair of C code files.
@@ -6,10 +8,10 @@ the dungeon and outputs a dungeon.h and dungeon.c pair of C code files.
 The nontrivial part of this is the compilation of the YAML for
 movement rules to the travel array that's actually used by
 playermove().
-
-Copyright (c) 2017 by Eric S. Raymond
-SPDX-License-Identifier: BSD-2-clause
 """
+
+# pylint: disable=consider-using-f-string,line-too-long,invalid-name,missing-function-docstring,too-many-branches,global-statement,multiple-imports,too-many-locals,too-many-statements,too-many-nested-blocks,no-else-return,raise-missing-from,redefined-outer-name
+
 import sys, yaml
 
 YAML_NAME = "adventure.yaml"
@@ -134,6 +136,7 @@ def get_objects(obj):
         }},
     }},
 """
+    max_state = 0
     obj_str = ""
     for (i, item) in enumerate(obj):
         attr = item[1]
@@ -157,6 +160,7 @@ def get_objects(obj):
                 statedefines += "/* States for %s */\n" % item[0]
                 for (n, label) in enumerate(labels):
                     statedefines += "#define %s\t%d\n" % (label, n)
+                    max_state = max(max_state, n)
                 statedefines += "\n"
         sounds_str = ""
         if attr.get("sounds") is None:
@@ -190,6 +194,7 @@ def get_objects(obj):
         treasure = "true" if attr.get("treasure") else "false"
         obj_str += template.format(i, item[0], words_str, i_msg, locs[0], locs[1], treasure, descriptions_str, sounds_str, texts_str, changes_str)
     obj_str = obj_str[:-1] # trim trailing newline
+    statedefines += "/* Maximum state value */\n#define MAX_STATE %d\n" % max_state
     return obj_str
 
 def get_obituaries(obit):
@@ -524,7 +529,7 @@ def get_travel(travel):
     return out
 
 if __name__ == "__main__":
-    with open(YAML_NAME, "r") as f:
+    with open(YAML_NAME, "r", encoding='ascii', errors='surrogateescape') as f:
         db = yaml.safe_load(f)
 
     locnames = [x[0] for x in db["locations"]]
@@ -536,10 +541,10 @@ if __name__ == "__main__":
                                  db["objects"])
     ignore = ""
     try:
-        with open(H_TEMPLATE_PATH, "r") as htf:
+        with open(H_TEMPLATE_PATH, "r", encoding='ascii', errors='surrogateescape') as htf:
             # read in dungeon.h template
             h_template = DONOTEDIT_COMMENT + htf.read()
-        with open(C_TEMPLATE_PATH, "r") as ctf:
+        with open(C_TEMPLATE_PATH, "r", encoding='ascii', errors='surrogateescape') as ctf:
             # read in dungeon.c template
             c_template = DONOTEDIT_COMMENT + ctf.read()
     except IOError as e:
@@ -587,10 +592,10 @@ if __name__ == "__main__":
         state_definitions  = statedefines
     )
 
-    with open(H_NAME, "w") as hf:
+    with open(H_NAME, "w", encoding='ascii', errors='surrogateescape') as hf:
         hf.write(h)
 
-    with open(C_NAME, "w") as cf:
+    with open(C_NAME, "w", encoding='ascii', errors='surrogateescape') as cf:
         cf.write(c)
 
 # end
diff --git a/make_graph.py b/make_graph.py
index 82b86af..63e440a 100755
--- a/make_graph.py
+++ b/make_graph.py
@@ -1,18 +1,20 @@
 #!/usr/bin/env python3
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 """\
 usage: make-graph.py [-a] -d] [-m] [-s]
 
 Make a DOT graph of Colossal Cave.
 
 -a = emit graph of entire dungeon
--d = emit graoh of mazw all different
+-d = emit graph of maze all different
 -f = emit graph of forest locations
 -m = emit graph of maze all alike
 -s = emit graph of non-forest surface locations
 -v = include internal symbols in room labels
 """
-# Copyright (c) 2017 by Eric S. Raymond
-# SPDX-License-Identifier: BSD-2-clause
+
+# pylint: disable=consider-using-f-string,line-too-long,invalid-name,missing-function-docstring,multiple-imports,redefined-outer-name
 
 import sys, getopt, yaml
 
@@ -68,7 +70,7 @@ def roomlabel(loc):
     return description
 
 # A forwarder is a location that you can't actually stop in - when you go there
-# it ships some message (which is the point) then shifts you to a nexr location.
+# it ships some message (which is the point) then shifts you to a next location.
 # A forwarder has a zero-length array of notion verbs in its travel section.
 #
 # Here is an example forwarder declaration:
@@ -95,7 +97,7 @@ def forward(loc):
     return loc
 
 def reveal(objname):
-    "Should this object be revealed when mappinmg?"
+    "Should this object be revealed when mapping?"
     if "OBJ_" in objname:
         return False
     if objname == "VEND":
@@ -104,7 +106,7 @@ def reveal(objname):
     return not obj.get("immovable")
 
 if __name__ == "__main__":
-    with open("adventure.yaml", "r") as f:
+    with open("adventure.yaml", "r", encoding='ascii', errors='surrogateescape') as f:
         db = yaml.safe_load(f)
 
     location_lookup = dict(db["locations"])
@@ -146,8 +148,8 @@ if __name__ == "__main__":
                 startlocs[location] = [objname]
 
     # Compute reachability, using forwards.
-    # Dictionary ke6y is (from, to) iff its a valid link,
-    # value is correspoinding motion verbs.
+    # Dictionary key is (from, to) iff its a valid link,
+    # value is corresponding motion verbs.
     links = {}
     nodes = []
     for (loc, attrs) in db["locations"]:
diff --git a/misc.c b/misc.c
index cf404f7..5aebb2a 100644
--- a/misc.c
+++ b/misc.c
@@ -1,9 +1,9 @@
 /*
- * I/O and support riutines.
+ * I/O and support routines.
  *
- * Copyright (c) 1977, 2005 by Will Crowther and Don Woods
- * Copyright (c) 2017 by Eric S. Raymond
- * SPDX-License-Identifier: BSD-2-clause
+ * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods
+ * SPDX-FileCopyrightText: 2017 by Eric S. Raymond
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <unistd.h>
@@ -222,7 +222,7 @@ static char* get_input(void)
     printf("\n");
 
     char* input;
-    while (true) {
+    for (;;) {
         input = myreadline(input_prompt);
 
         if (input == NULL) // Got EOF; return with it.
@@ -335,13 +335,11 @@ bool yes_or_no(const char* question, const char* yes_response, const char* no_re
 
         free(firstword);
 
-        if (yes == 0 ||
-            y == 0) {
+        if (yes == 0 || y == 0) {
             speak(yes_response);
             outcome = true;
             break;
-        } else if (no == 0 ||
-                   n == 0) {
+        } else if (no == 0 || n == 0) {
             speak(no_response);
             outcome = false;
             break;
@@ -411,7 +409,7 @@ static bool is_valid_int(const char *str)
     if (!*str)
         return false; // LCOV_EXCL_LINE
 
-    // Check for non-digit chars in the rest of the stirng.
+    // Check for non-digit chars in the rest of the string.
     while (*str) {
         if (!isdigit(*str))
             return false;
@@ -476,7 +474,7 @@ static void get_vocab_metadata(const char* word, vocab_t* id, word_type_t* type)
 static void tokenize(char* raw, command_t *cmd)
 {
     /*
-     * Be caereful about modifing this. We do not want to nuke the
+     * Be careful about modifying this. We do not want to nuke the
      * the speech part or ID from the previous turn.
      */
     memset(&cmd->word[0].raw, '\0', sizeof(cmd->word[0].raw));
@@ -490,7 +488,7 @@ static void tokenize(char* raw, command_t *cmd)
     /* (ESR) In oldstyle mode, simulate the uppercasing and truncating
      * effect on raw tokens of packing them into sixbit characters, 5
      * to a 32-bit word.  This is something the FORTRAN version did
-     * becuse archaic FORTRAN had no string types.  Don Wood's
+     * because archaic FORTRAN had no string types.  Don Wood's
      * mechanical translation of 2.5 to C retained the packing and
      * thus this misfeature.
      *
@@ -573,8 +571,8 @@ void juggle(obj_t object)
 {
     loc_t i, j;
 
-    i = game.place[object];
-    j = game.fixed[object];
+    i = game.objects[object].place;
+    j = game.objects[object].fixed;
     move(object, i);
     move(object + NOBJECTS, j);
 }
@@ -583,26 +581,31 @@ void move(obj_t object, loc_t where)
 /*  Place any object anywhere by picking it up and dropping it.  May
  *  already be toting, in which case the carry is a no-op.  Mustn't
  *  pick up objects which are not at any loc, since carry wants to
- *  remove objects from game.atloc chains. */
+ *  remove objects from game atloc chains. */
 {
     loc_t from;
 
     if (object > NOBJECTS)
-        from = game.fixed[object - NOBJECTS];
+        from = game.objects[object - NOBJECTS].fixed;
     else
-        from = game.place[object];
+        from = game.objects[object].place;
     /* (ESR) Used to check for !SPECIAL(from). I *think* that was wrong... */
     if (from != LOC_NOWHERE && from != CARRIED)
         carry(object, from);
     drop(object, where);
 }
 
-loc_t put(obj_t object, loc_t where, int pval)
+void put(obj_t object, loc_t where, int pval)
 /*  put() is the same as move(), except it returns a value used to set up the
  *  negated game.prop values for the repository objects. */
 {
     move(object, where);
-    return STASHED(pval);
+    /* (ESR) Read this in combination with the macro defintions in advebt.h.
+     */
+    game.objects[object].prop = PROP_STASHIFY(pval);
+#ifdef PROP_SET_SEEN
+    PROP_SET_SEEN(object);
+#endif
 }
 
 void carry(obj_t object, loc_t where)
@@ -613,18 +616,25 @@ void carry(obj_t object, loc_t where)
     int temp;
 
     if (object <= NOBJECTS) {
-        if (game.place[object] == CARRIED)
+        if (game.objects[object].place == CARRIED)
             return;
-        game.place[object] = CARRIED;
-
+        game.objects[object].place = CARRIED;
+
+	/*
+	 * Without this conditional your inventory is overcounted
+	 * when you pick up the bird while it's caged. This fixes
+	 * a cosmetic bug in the original.
+	 *
+	 * Possibly this check should be skipped whwn oldstyle is on.
+	 */
         if (object != BIRD)
             ++game.holdng;
     }
-    if (game.atloc[where] == object) {
-        game.atloc[where] = game.link[object];
+    if (game.locs[where].atloc == object) {
+        game.locs[where].atloc = game.link[object];
         return;
     }
-    temp = game.atloc[where];
+    temp = game.locs[where].atloc;
     while (game.link[temp] != object) {
         temp = game.link[temp];
     }
@@ -632,28 +642,27 @@ void carry(obj_t object, loc_t where)
 }
 
 void drop(obj_t object, loc_t where)
-/*  Place an object at a given loc, prefixing it onto the game.atloc list.  Decr
+/*  Place an object at a given loc, prefixing it onto the game atloc list.  Decr
  *  game.holdng if the object was being toted. No state change on the object. */
 {
     if (object > NOBJECTS)
-        game.fixed[object - NOBJECTS] = where;
+        game.objects[object - NOBJECTS].fixed = where;
     else {
-        if (game.place[object] == CARRIED)
+        if (game.objects[object].place == CARRIED)
             if (object != BIRD)
                 /* The bird has to be weightless.  This ugly hack (and the
-                 * corresponding code in the drop function) brought to you
+                 * corresponding code in the carry function) brought to you
                  * by the fact that when the bird is caged, we need to be able
                  * to either 'take bird' or 'take cage' and have the right thing
                  * happen.
                  */
                 --game.holdng;
-        game.place[object] = where;
+        game.objects[object].place = where;
     }
-    if (where == LOC_NOWHERE ||
-        where == CARRIED)
+    if (where == LOC_NOWHERE || where == CARRIED)
         return;
-    game.link[object] = game.atloc[where];
-    game.atloc[where] = object;
+    game.link[object] = game.locs[where].atloc;
+    game.locs[where].atloc = object;
 }
 
 int atdwrf(loc_t where)
@@ -668,9 +677,9 @@ int atdwrf(loc_t where)
         return at;
     at = -1;
     for (int i = 1; i <= NDWARVES - 1; i++) {
-        if (game.dloc[i] == where)
+        if (game.dwarves[i].loc == where)
             return i;
-        if (game.dloc[i] != 0)
+        if (game.dwarves[i].loc != 0)
             at = 0;
     }
     return at;
@@ -692,7 +701,7 @@ bool tstbit(int mask, int bit)
 }
 
 void set_seed(int32_t seedval)
-/* Set the LCG seed */
+/* Set the LCG1 seed */
 {
     game.lcg_x = seedval % LCG_M;
     if (game.lcg_x < 0) {
@@ -711,6 +720,9 @@ static int32_t get_next_lcg_value(void)
 {
     int32_t old_x = game.lcg_x;
     game.lcg_x = (LCG_A * game.lcg_x + LCG_C) % LCG_M;
+    if (settings.debug) {
+	printf("# random %d\n", old_x); // LCOV_EXCL_LINE
+    }
     return old_x;
 }
 
@@ -731,7 +743,7 @@ void bug(enum bugtype num, const char *error_string)
 void state_change(obj_t obj, int state)
 /* Object must have a change-message list for this to be useful; only some do */
 {
-    game.prop[obj] = state;
+    game.objects[obj].prop = state;
     pspeak(obj, change, true, state);
 }
 
diff --git a/notes.adoc b/notes.adoc
index 5e32ebb..b9ce8b1 100644
--- a/notes.adoc
+++ b/notes.adoc
@@ -1,5 +1,7 @@
 = Open Adventure Maintainer's Notes =
 by Eric S. Raymond
+// SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+// SPDX-License-Identifier: CC-BY-4.0
 
 In which we explain what has been done to this code since Don Woods
 authorized us to ship it under an open-source license.  There's a
@@ -13,7 +15,9 @@ the game; Jason signed on early in the process to help. The assistance
 of Peje Nilsson in restructuring some particularly grotty gotos is
 gratefully acknowledged. Petr Voropaev contributed fuzz testing and
 code cleanups. Aaron Traas did a lot of painstaking work to improve
-test coverage, and factored out the last handful of gotos.
+test coverage, and factored out the last handful of gotos.  Ryan
+Sarson nudged us into fixing a longstannding minor bug in the
+handling of incorrect magic-word sequebcesm, 
 
 == Nomenclature ==
 
@@ -45,16 +49,19 @@ future as a Python or Go translation seems possible, even probable.
 
 Bug fixes:
 
-* The caged bird to be counted as two items in your inventory.
+* The caged bird used to be counted as two items in your inventory.
 
 * Reading the relocated Witt's End sign in the endgame didn't work right.
 
 * Oyster was readable after first gotten even when not carried.
 
-* Behavior when saying the giant's magic words outside his room wasn't
-  quite correct - the game responded as though the player were in
-  the room ("...can't you read?"). The new message is "Nothing happens."
- 
+* Response to an attempt to unlock the oyster while carrying it was incorrect. 
+
+* Behavior when saying the giant's magic words before having seen them
+  wasn't quite correct - the game responded as though the player had
+  already read them ("...can't you read?"). The new message is "Well,
+  that was remarkably pointless!"  The -o option reverts this change.
+
 * Attempting to extinguish an unlit urn caused it to lose its oil.
 
 * "A crystal bridge now spans the fissure." (progressive present) was
@@ -62,14 +69,11 @@ Bug fixes:
   bridge spans the fissure." (timeless present).
 
 * A few minor typos have been corrected: absence of capitalization on
-  "Swiss" and "Persian", inconsistent selling of "imbedded" vs. "embedded",
-  "eying" for "eyeing". "thresholds" for "threshholds".
+  "Swiss" and "Persian", inconsistent spelling of "imbedded" vs. "embedded",
+  "eying" for "eyeing", "thresholds" for "threshholds".
 
 * Under odd circumstances (dropping rug or vase outdoors) the game could
-  say "floor" when it should say "ground" (or "dirt", or something).
-
-* Bird starts uncaged in the endgame. This is an accidental change
-  that doesn't seem worth the effort to fix.
+  formerly say "floor" when it should say "ground" (or "dirt", or something).
 
 Enhancements:
 
@@ -94,6 +98,7 @@ that random events (dwarf & pirate appearances, the bird's magic word)
 will be reproducible.
 
 A "version" command has been added. This has no effect on gameplay.
+
 The text displayed by the "news" command has been updated.
 
 A -l command-line option has been added. When this is given (with a
@@ -117,11 +122,28 @@ FORTRAN-derived code that formerly implemented the save/restore
 functions; without C's fread(3)/fwrite() and structs it was
 necessarily pretty ugly by modern standards. Encryption and
 checksumming have been discarded - it's pointless to try
-tamper-proofing saves when everyone has the source code.
+tamper-proofing saves when everyone has the source code. However
+the game still integrity-checks savefiles on resume, including an
+abort if the endianness of the restoring machine does not match that of
+the saving machine.  There is a magic-cookie header on the saves so
+in theory they could be identified by programs like file(1).
+
+Save and resume filenames are stripped of leading and trailing
+whitespace before processing.
 
 A -r command-line option has been added. When it is given (with a file
 path argument) it is functionally equivalent to a RESTORE command.
 
+An -a command-line option has been added (comditionally on
+ADVENT_AUTOSAVE) for use in BBS door systems.  When this option is
+given, the game roads from the specified filename argument on startup
+and saves to it on quit or a received signal. There is a new nmessage
+to inform the user about this.
+
+The game can be built in a mode that entirely disables save/resume
+(-DADVENT_NOSAVE). If the game had been built this way, a diagnostic is
+emitted if you try to save or resume.
+
 == Translation ==
 
 The 2.5 code was a mechanical C translation of a FORTRAN original.
@@ -158,6 +180,9 @@ afl (American Fuzzy Lop).  We've found and fixed some crashers in
 our new code (which occasionally uses malloc(3)), but none as yet
 in Don's old code (which didn't).
 
+After version 1.11, correctness was carefully checked against the
+behavior of a binary from before the big refactoring.
+
 The code falls short of being fully modern C in the following
 ways:
 
@@ -188,7 +213,7 @@ messages with the objects that conceptually own them.
 We consider this project finished. All issues and TODOs have been
 cleared, behavior has been carefully checked against original ADVENT,
 no future demand for new features is expected, and the test suite has
-100% code coverage.  If the toolchain bit-rots out from under it,
-we will fix that.
+100% code coverage.  If new bugs appear the toolchain bit-rots out
+from under underneath, we will fix those problems.
 
 // end
diff --git a/saveresume.c b/saveresume.c
index b5205d3..70b9461 100644
--- a/saveresume.c
+++ b/saveresume.c
@@ -4,13 +4,14 @@
  * (ESR) This replaces  a bunch of particularly nasty FORTRAN-derived code;
  * see the history.adoc file in the source distribution for discussion.
  *
- * Copyright (c) 1977, 2005 by Will Crowther and Don Woods
- * Copyright (c) 2017 by Eric S. Raymond
- * SPDX-License-Identifier: BSD-2-clause
+ * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods
+ * SPDX-FileCopyrightText: 2017 by Eric S. Raymond
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 #include <time.h>
 #include <inttypes.h>
 
@@ -18,36 +19,22 @@
 #include "dungeon.h"
 
 /*
- * Bump on save format change.
- *
- * Note: Verify that the tests run clean before bumping this, then rebuild the check
- * files afterwards.  Otherwise you will get a spurious failure due to the old version
- * having been generated into a check file.
+ * Use this to detect endianness mismatch.  Can't be unchanged by byte-swapping.
  */
-#define VRSION	29
+#define ENDIAN_MAGIC	2317
 
-/*
- * If you change the first three members, the resume function may not properly
- * reject saves from older versions.  Yes, this glues us to a hardware-
- * dependent length of int.  Later members can change, but bump the version
- * when you do that.
- */
-struct save_t {
-    int64_t savetime;
-    int32_t mode;		/* not used, must be present for version detection */
-    int32_t version;
-    struct game_t game;
-};
 struct save_t save;
 
 #define IGNORE(r) do{if (r){}}while(0)
 
-int savefile(FILE *fp, int32_t version)
+int savefile(FILE *fp)
 /* Save game to file. No input or output from user. */
 {
-    save.savetime = time(NULL);
-    save.mode = -1;
-    save.version = (version == 0) ? VRSION : version;
+    memcpy(&save.magic, ADVENT_MAGIC, sizeof(ADVENT_MAGIC));
+    if (save.version == 0)
+	save.version = SAVE_VERSION;
+    if (save.canary == 0)
+	save.canary = ENDIAN_MAGIC;
 
     save.game = game;
     IGNORE(fwrite(&save, sizeof(struct save_t), 1, fp));
@@ -55,15 +42,35 @@ int savefile(FILE *fp, int32_t version)
 }
 
 /* Suspend and resume */
+
+static char *strip(char *name)
+{
+    // Trim leading whitespace
+    while(isspace((unsigned char)*name))
+	name++;	// LCOV_EXCL_LINE
+    if(*name != '\0') {
+	// Trim trailing whitespace;
+	// might be left there by autocomplete
+	char *end = name + strlen(name) - 1;
+	while(end > name && isspace((unsigned char)*end))
+	    end--;
+	// Write new null terminator character
+	end[1] = '\0';
+    }
+
+    return name;
+}
+
 int suspend(void)
 {
     /*  Suspend.  Offer to save things in a file, but charging
      *  some points (so can't win by using saved games to retry
      *  battles or to start over after learning zzword).
-     *  If ADVENT_NOSAVE is defined, do nothing instead. */
+     *  If ADVENT_NOSAVE is defined, gripe instead. */
 
-#ifdef ADVENT_NOSAVE
-    return GO_UNKNOWN;
+#if defined ADVENT_NOSAVE || defined ADVENT_AUTOSAVE
+    rspeak(SAVERESUME_DISABLED);
+    return GO_TOP;
 #endif
     FILE *fp = NULL;
 
@@ -76,13 +83,16 @@ int suspend(void)
         char* name = myreadline("\nFile name: ");
         if (name == NULL)
             return GO_TOP;
-        fp = fopen(name, WRITE_MODE);
+	name = strip(name);
+	if (strlen(name) == 0)
+            return GO_TOP;	// LCOV_EXCL_LINE
+        fp = fopen(strip(name), WRITE_MODE);
         if (fp == NULL)
             printf("Can't open file %s, try again.\n", name);
         free(name);
     }
 
-    savefile(fp, VRSION);
+    savefile(fp);
     fclose(fp);
     rspeak(RESUME_HELP);
     exit(EXIT_SUCCESS);
@@ -91,15 +101,15 @@ int suspend(void)
 int resume(void)
 {
     /*  Resume.  Read a suspended game back from a file.
-     *  If ADVENT_NOSAVE is defined, do nothing instead. */
+     *  If ADVENT_NOSAVE is defined, gripe instead. */
 
-#ifdef ADVENT_NOSAVE
-    return GO_UNKNOWN;
+#if defined ADVENT_NOSAVE || defined ADVENT_AUTOSAVE
+    rspeak(SAVERESUME_DISABLED);
+    return GO_TOP;
 #endif
     FILE *fp = NULL;
 
-    if (game.loc != 1 ||
-        game.abbrev[1] != 1) {
+    if (game.loc != LOC_START || game.locs[LOC_START].abbrev != 1) {
         rspeak(RESUME_ABANDON);
         if (!yes_or_no(arbitrary_messages[THIS_ACCEPTABLE], arbitrary_messages[OK_MAN], arbitrary_messages[OK_MAN]))
             return GO_CLEAROBJ;
@@ -107,12 +117,12 @@ int resume(void)
 
     while (fp == NULL) {
         char* name = myreadline("\nFile name: ");
-        // Autocomplete can leave the input with an extra trailing space.
-        if (name != NULL && strlen(name) > 0 && name[strlen(name) - 1] == ' ')
-            name[strlen(name) - 1] = '\0';
         if (name == NULL)
             return GO_TOP;
-        fp = fopen(name, READ_MODE);
+	name = strip(name);
+	if (strlen(name) == 0)
+            return GO_TOP;	// LCOV_EXCL_LINE
+	fp = fopen(name, READ_MODE);
         if (fp == NULL)
             printf("Can't open file %s, try again.\n", name);
         free(name);
@@ -125,16 +135,22 @@ int restore(FILE* fp)
 {
     /*  Read and restore game state from file, assuming
      *  sane initial state.
-     *  If ADVENT_NOSAVE is defined, do nothing instead. */
+     *  If ADVENT_NOSAVE is defined, gripe instead. */
 #ifdef ADVENT_NOSAVE
-    return GO_UNKNOWN;
+    rspeak(SAVERESUME_DISABLED)
+    return GO_TOP;
 #endif
 
     IGNORE(fread(&save, sizeof(struct save_t), 1, fp));
     fclose(fp);
-    if (save.version != VRSION) {
-        rspeak(VERSION_SKEW, save.version / 10, MOD(save.version, 10), VRSION / 10, MOD(VRSION, 10));
-    } else if (is_valid(save.game)) {
+    if (memcmp(save.magic, ADVENT_MAGIC, sizeof(ADVENT_MAGIC)) != 0 || save.canary != ENDIAN_MAGIC)
+	rspeak(BAD_SAVE);
+    else if (save.version != SAVE_VERSION) {
+        rspeak(VERSION_SKEW, save.version / 10, MOD(save.version, 10), SAVE_VERSION / 10, MOD(SAVE_VERSION, 10));
+    } else if (!is_valid(save.game)) {
+	rspeak(SAVE_TAMPERING);
+	exit(EXIT_SUCCESS);
+    } else {
         game = save.game;
     }
     return GO_TOP;
@@ -143,8 +159,8 @@ int restore(FILE* fp)
 bool is_valid(struct game_t valgame)
 {
     /*  Save files can be roughly grouped into three groups:
-     *  With valid, reaceable state, with valid, but unreachable
-     *  state and with invaild state. We check that state is
+     *  With valid, reachable state, with valid, but unreachable
+     *  state and with invalid state. We check that state is
      *  valid: no states are outside minimal or maximal value
      */
 
@@ -174,15 +190,15 @@ bool is_valid(struct game_t valgame)
     }
     /*  Bounds check for location arrays */
     for (int i = 0; i <= NDWARVES; i++) {
-        if (valgame.dloc[i]  < -1 || valgame.dloc[i]  > NLOCATIONS  ||
-            valgame.odloc[i] < -1 || valgame.odloc[i] > NLOCATIONS) {
+        if (valgame.dwarves[i].loc  < -1 || valgame.dwarves[i].loc  > NLOCATIONS  ||
+            valgame.dwarves[i].oldloc < -1 || valgame.dwarves[i].oldloc > NLOCATIONS) {
             return false;	// LCOV_EXCL_LINE
         }
     }
 
     for (int i = 0; i <= NOBJECTS; i++) {
-        if (valgame.place[i] < -1 || valgame.place[i] > NLOCATIONS  ||
-            valgame.fixed[i] < -1 || valgame.fixed[i] > NLOCATIONS) {
+        if (valgame.objects[i].place < -1 || valgame.objects[i].place > NLOCATIONS  ||
+            valgame.objects[i].fixed < -1 || valgame.objects[i].fixed > NLOCATIONS) {
             return false;	// LCOV_EXCL_LINE
         }
     }
@@ -202,7 +218,7 @@ bool is_valid(struct game_t valgame)
     int temp_tally = 0;
     for (int treasure = 1; treasure <= NOBJECTS; treasure++) {
         if (objects[treasure].is_treasure) {
-            if (valgame.prop[treasure] == STATE_NOTFOUND) {
+            if (PROP_IS_NOTFOUND2(valgame, treasure)) {
                 ++temp_tally;
             }
         }
@@ -213,35 +229,14 @@ bool is_valid(struct game_t valgame)
 
     /* Check that properties of objects aren't beyond expected */
     for (obj_t obj = 0; obj <= NOBJECTS; obj++) {
-        if (valgame.prop[obj] < STATE_NOTFOUND || valgame.prop[obj] > 1) {
-            switch (obj) {
-            case RUG:
-            case DRAGON:
-            case BIRD:
-            case BOTTLE:
-            case PLANT:
-            case PLANT2:
-            case TROLL:
-            case URN:
-            case EGGS:
-            case VASE:
-            case CHAIN:
-                if (valgame.prop[obj] == 2) // There are multiple different states, but it's convenient to clump them together
-                    continue;
-            /* FALLTHRU */
-            case BEAR:
-                if (valgame.prop[BEAR] == CONTENTED_BEAR || valgame.prop[BEAR] == BEAR_DEAD)
-                    continue;
-            /* FALLTHRU */
-            default:
-                return false;	// LCOV_EXCL_LINE
-            }
+        if (PROP_IS_INVALID(valgame.objects[obj].prop)) {
+	    return false;	// LCOV_EXCL_LINE
         }
     }
 
     /* Check that values in linked lists for objects in locations are inside bounds */
     for (loc_t loc = LOC_NOWHERE; loc <= NLOCATIONS; loc++) {
-        if (valgame.atloc[loc] < NO_OBJECT || valgame.atloc[loc] > NOBJECTS * 2) {
+        if (valgame.locs[loc].atloc < NO_OBJECT || valgame.locs[loc].atloc > NOBJECTS * 2) {
             return false;	// LCOV_EXCL_LINE
         }
     }
diff --git a/score.c b/score.c
index 275a358..c0a0277 100644
--- a/score.c
+++ b/score.c
@@ -1,9 +1,9 @@
 /*
  * Scoring and wrap-up.
  *
- * Copyright (c) 1977, 2005 by Will Crowther and Don Woods
- * Copyright (c) 2017 by Eric S. Raymond
- * SPDX-License-Identifier: BSD-2-clause
+ * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods
+ * SPDX-FileCopyrightText: 2017 by Eric S. Raymond
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <stdlib.h>
 #include "advent.h"
@@ -48,9 +48,9 @@ int score(enum termination mode)
                 k = 14;
             if (i > CHEST)
                 k = 16;
-            if (game.prop[i] > STATE_NOTFOUND)
+            if (!PROP_IS_STASHED(i) && !PROP_IS_NOTFOUND(i))
                 score += 2;
-            if (game.place[i] == LOC_BUILDING && game.prop[i] == STATE_FOUND)
+            if (game.objects[i].place == LOC_BUILDING && PROP_IS_FOUND(i))
                 score += k - 2;
             mxscor += k;
         }
@@ -86,7 +86,7 @@ int score(enum termination mode)
     mxscor += 45;
 
     /* Did he come to Witt's End as he should? */
-    if (game.place[MAGAZINE] == LOC_WITTSEND)
+    if (game.objects[MAGAZINE].place == LOC_WITTSEND)
         score += 1;
     mxscor += 1;
 
@@ -96,7 +96,7 @@ int score(enum termination mode)
 
     /* Deduct for hints/turns/saves. Hints < 4 are special; see database desc. */
     for (int i = 0; i < NHINTS; i++) {
-        if (game.hinted[i])
+        if (game.hints[i].used)
             score = score - hints[i].penalty;
     }
     if (game.novice)
@@ -117,6 +117,9 @@ void terminate(enum termination mode)
 /* End of game.  Let's tell him all about it. */
 {
     int points = score(mode);
+#if defined ADVENT_AUTOSAVE
+    autosave();
+#endif
 
     if (points + game.trnluz + 1 >= mxscor && game.trnluz != 0)
         rspeak(TOOK_LONG);
@@ -126,13 +129,16 @@ void terminate(enum termination mode)
     for (int i = 1; i <= (int)NCLASSES; i++) {
         if (classes[i].threshold >= points) {
             speak(classes[i].message);
-            i = classes[i].threshold + 1 - points;
-            rspeak(NEXT_HIGHER, i, i);
+	    if (i < (int)NCLASSES) {
+		int nxt = classes[i].threshold + 1 - points;
+		rspeak(NEXT_HIGHER, nxt, nxt);
+	    } else {
+		rspeak(NO_HIGHER);
+	    }
             exit(EXIT_SUCCESS);
         }
     }
     rspeak(OFF_SCALE);
-    rspeak(NO_HIGHER);
     exit(EXIT_SUCCESS);
 }
 
diff --git a/templates/coverage_dungeon.html.tpl b/templates/coverage_dungeon.html.tpl
index 372c43f..164473e 100644
--- a/templates/coverage_dungeon.html.tpl
+++ b/templates/coverage_dungeon.html.tpl
@@ -1,3 +1,7 @@
+<--
+SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+SPDX-License-Identifier: BSD-2-Clause
+-->
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 <html lang="en">
 <head>
diff --git a/templates/dungeon.c.tpl b/templates/dungeon.c.tpl
index dbc28a6..d1604a5 100644
--- a/templates/dungeon.c.tpl
+++ b/templates/dungeon.c.tpl
@@ -1,3 +1,8 @@
+/*
+SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+SPDX-License-Identifier: BSD-2-Clause
+*/
+
 #include "{h_file}"
 
 const char* arbitrary_messages[] = {{
@@ -48,4 +53,4 @@ const travelop_t travel[] = {{
 
 const char *ignore = "{ignore}";
 
-/* end */
\ No newline at end of file
+/* end */
diff --git a/templates/dungeon.h.tpl b/templates/dungeon.h.tpl
index e42ab07..ab3d6d7 100644
--- a/templates/dungeon.h.tpl
+++ b/templates/dungeon.h.tpl
@@ -1,3 +1,7 @@
+/*
+SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+SPDX-License-Identifier: BSD-2-Clause
+*/
 #ifndef DUNGEON_H
 #define DUNGEON_H
 
diff --git a/tests/Makefile b/tests/Makefile
index 59f2972..66280f4 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,4 +1,7 @@
-# Test-suite makefile for opeb-adventure
+# Test-suite makefile for open-adventure
+
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 
 # Use absolute path so tests that change working directory still use
 # scripts from parent directory.  Note that using $PWD seems to fail
@@ -29,14 +32,12 @@ TESTLOADS := $(shell ls -1 *.log | sed '/.log/s///' | sort)
 
 check: savecheck
 	@make tap | tapview
-	@echo "=== No diff output is good news."
-	@-advent -x 2>/dev/null	# Get usage message into coverage tests
-	@-advent -l /dev/null <pitfall.log >/dev/null
+	@-advent -x 2>/dev/null	|| exit 0 # Get usage message into coverage tests
 
 .SUFFIXES: .chk
 
 clean:
-	rm -fr *~ adventure.text *.adv scratch.tmp
+	rm -fr *~ *.adv scratch.tmp *.ochk advent430 adventure.data
 
 # Show summary lines for all tests.
 testlist:
@@ -47,39 +48,50 @@ listcheck:
 	done
 
 # Generate bogus savegames.
-savegames:
-	@$(ECHO) "cheat: Generate save file with -900 deaths"
+cheat_numdie.adv:
 	@$(PARDIR)/cheat -d -900 -o cheat_numdie.adv > /tmp/cheat_numdie
-	@$(ECHO) "cheat: Generate save file with -1000 deaths"
+cheat_numdie1000.adv:
 	@$(PARDIR)/cheat -d -1000 -o cheat_numdie1000.adv > /tmp/cheat_numdie1000
-	@$(ECHO) "cheat: Generate save file with version -1337"
+cheat_savetamper.adv:
+	@$(PARDIR)/cheat -d 2000 -o cheat_savetamper.adv > /tmp/cheat_savetamper
+resume_badversion.adv:
 	@$(PARDIR)/cheat -v -1337 -o resume_badversion.adv > /tmp/cheat_badversion
-	@$(ECHO) "cheat: Generate save file 1000 saves"
+thousand_saves.adv:
 	@$(PARDIR)/cheat -s -1000 -o thousand_saves.adv > /tmp/cheat_1000saves
-	@$(ECHO) "cheat: Generate save file 1000 turns"
-	@$(PARDIR)/cheat -t -1000 -o thousand_saves.adv > /tmp/cheat_1000turns
-	@$(ECHO) "cheat: Generate save file 1000 turns"
-	@$(PARDIR)/cheat -l -1000 -o thousand_lamp.adv > /tmp/cheat_1000lamp
-	@rm -f /tmp/cheat*
+thousand_turns.adv:
+	@$(PARDIR)/cheat -t -1000 -o thousand_turns.adv > /tmp/cheat_1000turns
+thousand_limit.adv:
+	@$(PARDIR)/cheat -l -1000 -o thousand_limit.adv > /tmp/cheat_1000limit
+SGAMES = cheat_numdie.adv cheat_numdie1000.adv cheat_savetamper.adv resume_badversion.adv \
+	thousand_saves.adv thousand_turns.adv thousand_limit.adv
 
 # Force coverage of cheat edgecases
-savecheck: savegames
-	@$(ECHO) "TEST cheat: Bogus option for save file generation"
+scheck1:
 	@$(PARDIR)/cheat -QqQ 2> /tmp/coverage_cheat_batopt | true
-	@$(ECHO) "TEST cheat: No save file specified"
+	@./outcheck.sh "cheat: bogus option for save file generation"
+scheck2:
 	@$(PARDIR)/cheat 2>/dev/null | true
-	@$(ECHO) "TEST cheat: Fail to save because we omit -o"
+	@./outcheck.sh "cheat: No save file specified"
+scheck3:
 	@$(PARDIR)/cheat -d 1 2> /tmp/coverage_cheat_nooutput | true
-	@$(ECHO) "TEST cheat: Fail to save to invalid path"
+	@./outcheck.sh "cheat: doesn't save because we omit -o"
+scheck4:
 	@$(PARDIR)/cheat -o / 2> /tmp/coverage_cheat_badoutput | true
-	@$(ECHO) "TEST advent: Start with invalid file with -r"
-	@advent -r /badfilename < pitfall.log > /tmp/coverage_advent_readfail 2>&1 || exit 1
-	@$(ECHO) "TEST advent: Start with invalid file with -l"
-	@advent -l / < pitfall.log > /tmp/coverage_advent_logfail 2>&1 || exit 1
-	@$(ECHO) "TEST advent: Test -r with valid input"
-	@advent -r thousand_saves.adv < pitfall.log > /tmp/coverage_advent_readfail 2>&1 || exit 1
-	@rm -f /tmp/coverage*
-
+	@./outcheck.sh "cheat: doesn't save to invalid path"
+scheck5:
+	@$(advent) -r /badfilename < pitfall.log > /tmp/coverage_advent_readfail 2>&1 || exit 1
+	@./outcheck.sh "cheat: doesn't start with invalid file with -r"
+scheck6:
+	@$(advent) -l / < pitfall.log > /tmp/coverage_advent_logfail 2>&1 || exit 1
+	@./outcheck.sh "cheat: doesn't start with invalid file passed to -l"
+scheck7:
+	@$(advent) -r thousand_saves.adv < pitfall.log > /tmp/coverage_advent_readfail 2>&1 || exit 1
+	@./outcheck.sh "test -r with valid input"
+SCHECKS = scheck1 scheck2 scheck3 scheck4 scheck5 scheck6 scheck7
+
+# Don't run this from here, you'll get cryptic warnings and no good result
+# if the advent binary wasn't built with coverage flags.  Do "make clean coverage"
+# from the top-level directory.
 coverage: check
 	lcov -t "advent" -o $(PARDIR)/advent.info -c -d $(PARDIR) --gcov-tool=$(GCOV)
 	genhtml -o $(PARDIR)/coverage/ $(PARDIR)/advent.info
@@ -93,22 +105,77 @@ buildchecks: savegames
 	    OPTS=`sed -n /#options:/s///p <$${file}.log`; \
 	    advent $$OPTS <$${file}.log >$${file}.chk 2>&1 || exit 1; \
 	done; \
-	echo "inven" | advent isofoo.log /dev/stdin >multifile.chk
+	echo "inven" | advent issue36.log /dev/stdin >multifile.chk; \
 	rm -f scratch.tmp
 
 RUN_TARGETS=$(TESTLOADS:%=run-regress-%)
 $(RUN_TARGETS): run-regress-%: %.log
 	@(test=$(<:.log=); legend=$$(sed -n '/^## /s///p' <"$<" 2>/dev/null || echo "(no description)"); \
 	OPTS=`sed -n /#options:/s///p $<`; \
-	$(advent) $$OPTS <$< | tapdiffer "$<: $${legend}" "$${test}.chk")
+	$(advent) $$OPTS <$< | tapdiffer "$${test}: $${legend}" "$${test}.chk")
 
 multifile-regress:
-	@(echo "inven" | advent isofoo.log /dev/stdin) | tapdiffer "multifile: multiple-file test" multifile.chk
+	@(echo "inven" | advent issue36.log /dev/stdin) | tapdiffer "multifile: multiple-file test" multifile.chk
 
-TEST_TARGETS = $(RUN_TARGETS) multifile-regress
+TEST_TARGETS = $(SCHECKS) $(RUN_TARGETS) multifile-regress
 
-tap: count $(TEST_TARGETS)
+tap: count $(SGAMES) $(TEST_TARGETS)
+	@rm -f scratch.tmp /tmp/coverage* /tmp/cheat*
 count:
 	@echo 1..$(words $(TEST_TARGETS))
 
+foobar:
+	exit 1
+
+
+# The following machinery tests the game against a binary made from
+# the advent430 branch To use it, switch to that branch, build the
+# binary, run it once to generate adventure.data, then switch back to
+# master leaving advent430 and adventure.data in place (make clean
+# does not remove them).
+#
+# make clean                 # Clean up object files, laving a bare source tree
+# git checkout advent430     # Check out the advent430 branch
+# make                       # Build the advent430 binary
+# advent430                  # Run it.  Answer the novice question and quit
+# make clean                 # Remove .o files
+# git checkout master        # Go back to master branch
+# make                       # Rebuild advent.
+#
+# The diff file produced has corrected spellings in it. That's what oldfilter
+# is for, to massage out the original spellings and avoid noise diffs.
+# Diffs in amount of whitespace and trailing whitespace are ignored
+#
+# A magic comment of NOCOMPARE in a log file excludes it from this comparison.
+# making it a skipped test in the TAP view. First use of this was to avoid a
+# spurious mismatch on the news text. Other uses avoid spurious mismatches due
+# to bug fixes.
+#
+# When adding more tests, bear in mind that any game that continues after a
+# resurrection will need a NOCOMPARE. At some point in the forward port,
+# resurrection was accidentally changed in a way that messed wil the LCG chain.
+#
+# The *.chk files need not be up-to-date for this to work.
+#
+TAPFILTER=tapview
+oldcompare:
+	@if [ -f ../advent430 ]; then cp ../advent430 ../adventure.data .; else echo "advent430 nonexistent"; exit 1; fi
+	@-(for x in *.log; do \
+		stem=$${x%.log}; \
+		legend=$$(sed -n '/^## /s///p' <$$x 2>/dev/null || echo "(no description)"); \
+		if grep NOCOMPARE $$x >/dev/null; \
+			then echo "not ok - $${stem}.ochk: $${legend} # SKIP"; \
+			else \
+				./advent430 <$${stem}.log | oldfilter >$${stem}.ochk; \
+				../advent <$${stem}.log >$${stem}.log-new; \
+				./newfilter <$${stem}.log-new | tapdiffer -b "$${stem}: $${legend}" $${stem}.ochk; \
+			fi; \
+	done; \
+	echo 1..$(words $(shell ls *.log))) | $(TAPFILTER)
+	@rm *.ochk *-new advent430 adventure.data
+
+# List all NOMPARE tests.
+residuals:
+	@grep -n NOCOMPARE *.log
+
 # end
diff --git a/tests/README b/tests/README
index 1118056..d84dfd4 100644
--- a/tests/README
+++ b/tests/README
@@ -17,9 +17,9 @@ To see summary lines from all tests, 'make testlist'.  The summary lines
 are those led with ##; you should have one such descriptive line at the
 head of each file.
 
-To run the tests, "make regress".
+To run the tests, "make check".
 
-To remake the check files, "make buildregress".
+To remake the check files, "make buildchecks".
 
 == Composing tests ==
 
@@ -29,12 +29,8 @@ option giving a log path.  Commands will be captured to that log.
 To re-use a command sequence from an existing log, run advent and
 paste it to the advent command log from the clipboard.
 
-To see where we can use more tests, have a look at our test coverage
-report:
+To see where we can use more tests, "make coverage".
 
-http://esr.gitlab.io/open-adventure/coverage/
-
-Improvements in test coverage are always welcome.
 
 // end
 
diff --git a/tests/axebear.chk b/tests/axebear.chk
index 7cff028..ba465c2 100644
--- a/tests/axebear.chk
+++ b/tests/axebear.chk
@@ -1631,7 +1631,7 @@ There is a little axe lying beside the bear.
 
 The bear is locked to the wall with a golden chain!
 
-
+> 
 You scored 251 out of a possible 430, using 271 turns.
 
 You have reached "Junior Master" status.
diff --git a/tests/axebear.log b/tests/axebear.log
index 8498b21..27c0af5 100644
--- a/tests/axebear.log
+++ b/tests/axebear.log
@@ -1,4 +1,6 @@
 ## Observe axe after throwing at bear
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
diff --git a/tests/axeorama.chk b/tests/axeorama.chk
index 741ac50..fbb1d7b 100644
--- a/tests/axeorama.chk
+++ b/tests/axeorama.chk
@@ -652,7 +652,7 @@ mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
 A burly troll stands by the bridge and insists you throw him a
 treasure before you may cross.
 
-
+> 
 You scored 105 out of a possible 430, using 109 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/axeorama.log b/tests/axeorama.log
index 7d2e273..fd10948 100644
--- a/tests/axeorama.log
+++ b/tests/axeorama.log
@@ -1,4 +1,6 @@
 ## Test throwing axe at non-dwarves.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # Added coverage of LOC_DEADCRAWL and CROSS_BRIDGE
 n
 seed 1838473132
diff --git a/tests/isofoo.chk b/tests/badmagic.chk
similarity index 76%
rename from tests/isofoo.chk
rename to tests/badmagic.chk
index 1c0cbaf..08c8ffe 100644
--- a/tests/isofoo.chk
+++ b/tests/badmagic.chk
@@ -7,11 +7,14 @@ You are standing at the end of a road before a small brick building.
 Around you is a forest.  A small stream flows out of the building and
 down a gully.
 
-> foo
+> resume
+Can't open file y, try again.
 
-Nothing happens.
+Oops, that does not look like a valid save file.
 
+You're in front of building.
 
+> 
 You scored 32 out of a possible 430, using 1 turn.
 
 You are obviously a rank amateur.  Better luck next time.
diff --git a/tests/badmagic.log b/tests/badmagic.log
new file mode 100644
index 0000000..4ee9f10
--- /dev/null
+++ b/tests/badmagic.log
@@ -0,0 +1,8 @@
+## Resume from filename withoy the right magic at the front 
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE advent430 doesn't have this test
+n
+resume
+y
+../main.o
diff --git a/tests/barehands.chk b/tests/barehands.chk
index 38b0c05..f94685f 100644
--- a/tests/barehands.chk
+++ b/tests/barehands.chk
@@ -307,7 +307,7 @@ The blood-specked body of a huge green dead dragon lies to one side.
 
 For crying out loud, the poor thing is already dead!
 
-
+> 
 You scored 77 out of a possible 430, using 49 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/barehands.log b/tests/barehands.log
index 72fc3de..1ad2c32 100644
--- a/tests/barehands.log
+++ b/tests/barehands.log
@@ -1,4 +1,7 @@
 ## Get to dragon, refuse to use bare hands
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE Fails due uninteresting difference in whitespace process. 
 # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56
 n
 seed 1635997320
diff --git a/tests/bigfail.chk b/tests/bigfail.chk
index eebea66..df15f38 100644
--- a/tests/bigfail.chk
+++ b/tests/bigfail.chk
@@ -1800,746 +1800,12 @@ Oh dear, you seem to have gotten yourself killed.  I might be able to
 help you out, but I've never really done this before.  Do you want me
 to try to reincarnate you?
 
-> yes
-
-All right.  But don't blame me if something goes wr......
-                    --- POOF!! ---
-You are engulfed in a cloud of orange smoke.  Coughing and gasping,
-you emerge from the smoke and find....
-
-You're inside building.
-
-There is a richly-carved ebony statuette here!
-
-There is an emerald here the size of a plover's egg!
-
-There is a jewel-encrusted trident here!
-
-There is a platinum pyramid here, 8 inches on a side!
-
-There are diamonds here!
-
-There is an enormous ruby here!
-
-There are bars of silver here!
-
-There is a Persian rug spread out on the floor!
-
-There is a large sparkling nugget of gold here!
-
-A precious jade necklace has been dropped here!
-
-There is precious jewelry here!
-
-> inven
-
-You're not carrying anything.
-
-> out
-
-You're in front of building.
-
-There is a shiny brass lamp nearby.
-
-> take lamp
-
-OK
-
-> light lamp
-
-Your lamp is now on.
-
-> in
-
-You're inside building.
-
-There is a richly-carved ebony statuette here!
-
-There is an emerald here the size of a plover's egg!
-
-There is a jewel-encrusted trident here!
-
-There is a platinum pyramid here, 8 inches on a side!
-
-There are diamonds here!
-
-There is an enormous ruby here!
-
-There are bars of silver here!
-
-There is a Persian rug spread out on the floor!
-
-There is a large sparkling nugget of gold here!
-
-A precious jade necklace has been dropped here!
-
-There is precious jewelry here!
-
-> plugh
-
->>Foof!<<
-
-You're at "Y2".
-
-> s
-
-You're in n/s passage above e/w passage.
-
-> d
-
-You're in dirty passage.
-
-> bedquilt
-
-You're in Bedquilt.
-
-> n
-
-You're in large low room.
-
-> sw
-
-You're in sloping corridor.
-
-> up
-
-You're on sw side of chasm.
-
-There is a little axe here.
-
-There are many coins here!
-
-Off to one side lies a glistening pearl!
-
-There is a golden chain lying in a heap on the floor!
-
-The wreckage of a bridge (and a dead bear) can be seen at the bottom
-of the chasm.
-
-The troll is nowhere to be seen.
-
-> over
-
-There is no longer any way across the chasm.
-
-You're on sw side of chasm.
-
-There is a little axe here.
-
-There are many coins here!
-
-Off to one side lies a glistening pearl!
-
-There is a golden chain lying in a heap on the floor!
-
-The wreckage of a bridge (and a dead bear) can be seen at the bottom
-of the chasm.
-
-The troll is nowhere to be seen.
-
-> feed bear
-
-Don't be ridiculous!
-
-> attack bear
-
-For crying out loud, the poor thing is already dead!
-
-> take coins
-
-OK
-
-> take axe
-
-OK
-
-> sw
-
-You're in sloping corridor.
-
-> d
-
-You're in large low room.
-
-> se
-
-You're in Oriental Room.
-
-The floor is littered with worthless shards of pottery.
-
-> se
-
-You're in Swiss Cheese Room.
-
-> ne
-
-You are in Bedquilt, a long east/west passage with holes everywhere.
-To explore at random select north, south, up, or down.
-
-> e
-
-You're at complex junction.
-
-> up
-
-You're in dusty rock room.
-
-> e
-
-You're in dirty passage.
-
-> up
-
-You are in a low n/s passage at a hole in the floor.  The hole goes
-down to an e/w passage.
-
-> s
-
-You're in Hall of Mt King.
-
-> up
-
-You're in Hall of Mists.
-
-Rough stone steps lead up the dome.
-
-> w
-
-You're on east bank of fissure.
-
-A three foot black rod with a rusty star on an end lies nearby.
-
-A crystal bridge spans the fissure.
-
-> take rod
-
-OK
-
-> wave rod
-
-The crystal bridge has vanished!
-
-> across
-
-There is no way across the fissure.
-
-You're on east bank of fissure.
-
-> wave rod
-
-A crystal bridge now spans the fissure.
-
-> across
-
-You're on west bank of fissure.
-
-A crystal bridge spans the fissure.
-
-> w
-
-You're at west end of Hall of Mists.
-
-> w
-
-You're at east end of long hall.
-
-> w
-
-You're at west end of long hall.
-
-> s
-
-You are in a maze of twisty little passages, all different.
-
-> s
-
-You are in a maze of twisting little passages, all different.
-
-> sw
-
-You are in a twisting little maze of passages, all different.
-
-> se
-
-You are in a twisting maze of little passages, all different.
-
-> s
-
-You are in a little maze of twisting passages, all different.
-
-> s
-
-Dead end
-
-There is a massive vending machine here, swung back to reveal a
-southward passage.
-
-> drop coins
-
-There are fresh batteries here.
-
-> look
-
-Sorry, but I am not allowed to give more detail.  I will repeat the
-long description of your location.
-
-Dead end
-
-There are fresh batteries here.
-
-There is a massive vending machine here, swung back to reveal a
-southward passage.
-
-> n
-
-Your lamp is getting dim.  I'm taking the liberty of replacing the
-batteries.
-
-You are in a little maze of twisting passages, all different.
-
-> z
-
-OK
-
-> z
-
-Tsk!  A wizard wouldn't have to take 350 turns.  This is going to cost
-you a couple of points.
-
-OK
-
-> z
-
-OK
-
-> z
-
-OK
-
-> s
-
-Dead end
-
-Some worn-out batteries have been discarded nearby.
-
-There is a massive vending machine here, swung back to reveal a
-southward passage.
-
-> take batteries
-
-OK
-
-> n
-
-You are in a little maze of twisting passages, all different.
-
-> back
-
-Sorry, but the path twisted and turned so much that I can't figure
-out which way to go to get back.
-
-You are in a little maze of twisting passages, all different.
-
-> n
-
-You are in a little maze of twisty passages, all different.
-
-> nw
-
-You are in a maze of twisty little passages, all different.
-
-> d
-
-You're at west end of long hall.
-
-> drink
-
-Drink what?
-
-> e
-
-You're at east end of long hall.
-
-> e
-
-You're at west end of Hall of Mists.
-
-> n
-
-You have crawled through a very low wide passage parallel to and north
-of the Hall of Mists.
-
-You're on west bank of fissure.
-
-A crystal bridge spans the fissure.
-
-> w
-
-You're at west end of Hall of Mists.
-
-> w
-
-You're at east end of long hall.
-
-> n
-
-You are at a crossover of a high n/s passage and a low e/w one.
-
-> e
-
-You're in the west side chamber.
-
-> d
-
-There is no way to go that direction.
-
-You're in the west side chamber.
-
-> e
-
-You're in Hall of Mt King.
-
-> u
-
-There is a threatening little dwarf in the room with you!
-
-You're in Hall of Mists.
-
-Rough stone steps lead up the dome.
-
-> throw axe
-
-You killed a little dwarf.
-
-You are at one end of a vast hall stretching forward out of sight to
-the west.  There are openings to either side.  Nearby, a wide stone
-staircase leads downward.  The hall is filled with wisps of white mist
-swaying to and fro almost as if alive.  A cold wind blows up the
-staircase.  There is a passage at the top of a dome behind you.
-
-There is a little axe here.
-
-Rough stone steps lead up the dome.
-
-> d
-
-You're in Hall of Mt King.
-
-> n
-
-You're in n/s passage above e/w passage.
-
-> d
-
-You are in a dirty broken passage.  To the east is a crawl.  To the
-west is a large passage.  Above you is a hole to another passage.
-
-> e
-
-You are on the brink of a small clean climbable pit.  A crawl leads
-west.
-
-> d
-
-You are in the bottom of a small pit with a little stream, which
-enters and exits through tiny slits.
-
-> listen
-
-The stream is gurgling placidly.
-
-> u
-
-You're at brink of small pit.
-
-> w
-
-You're in dirty passage.
-
-> bedquilt
-
-You're in Bedquilt.
-
-> z
-
-OK
-
-> z
-
-OK
-
-> z
-
-OK
-
-> n
-
-You have crawled around in some little holes and wound up back in the
-main passage.
-
-You're in Bedquilt.
-
-> n
-
-You have crawled around in some little holes and wound up back in the
-main passage.
-
-You're in Bedquilt.
-
-> n
-
-You have crawled around in some little holes and wound up back in the
-main passage.
-
-You're in Bedquilt.
-
-> n
-
-You are in a secret canyon at a junction of three canyons, bearing
-north, south, and se.  The north one is as tall as the other two
-combined.
-
-> w
-
-There is no way to go that direction.
-
-You're at junction of three secret canyons.
-
-> n
-
-You're at a low window overlooking a huge pit, which extends up out of
-sight.  A floor is indistinctly visible over 50 feet below.  Traces of
-white mist cover the floor of the pit, becoming thicker to the left.
-Marks in the dust around the window would seem to indicate that
-someone has been here recently.  Directly across the pit from you and
-25 feet away there is a similar window looking into a lighted room.  A
-shadowy figure can be seen there peering back at you.
-
-The shadowy figure seems to be trying to attract your attention.
-
-> w
-
-You're at junction of three secret canyons.
-
-> s
-
-You are in a secret n/s canyon above a sizable passage.
-
-> s
-
-A large stalactite extends from the roof and almost reaches the floor
-below.  You could climb down it, and jump from it to the floor, but
-having done so you would be unable to reach it to climb back up.
-
-> n
-
-You are in a secret n/s canyon above a sizable passage.
-
-> s
-
-There are faint rustling noises from the darkness behind you.
-
-You're at top of stalactite.
-
-> n
-
-You are in a secret n/s canyon above a sizable passage.
-
-> n
-
-You're at junction of three secret canyons.
-
 > n
 
-You're at window on pit.
-
-The shadowy figure seems to be trying to attract your attention.
-
-> jump
-
-You are at the bottom of the pit with a broken neck.
-
-You clumsy oaf, you've done it again!  I don't know how long I can
-keep this up.  Do you want me to try reincarnating you again?
-
-> y
-
-Okay, now where did I put my orange smoke?....  >POOF!<
-Everything disappears in a dense cloud of orange smoke.
-
-You're inside building.
-
-There is a richly-carved ebony statuette here!
-
-There is an emerald here the size of a plover's egg!
-
-There is a jewel-encrusted trident here!
-
-There is a platinum pyramid here, 8 inches on a side!
-
-There are diamonds here!
-
-There is an enormous ruby here!
-
-There are bars of silver here!
-
-There is a Persian rug spread out on the floor!
-
-There is a large sparkling nugget of gold here!
-
-A precious jade necklace has been dropped here!
-
-There is precious jewelry here!
-
-> out
-
-You are standing at the end of a road before a small brick building.
-Around you is a forest.  A small stream flows out of the building and
-down a gully.
-
-There is a shiny brass lamp nearby.
-
-> take lamp
-
-OK
-
-> in
-
-You're inside building.
-
-There is a richly-carved ebony statuette here!
-
-There is an emerald here the size of a plover's egg!
-
-There is a jewel-encrusted trident here!
-
-There is a platinum pyramid here, 8 inches on a side!
-
-There are diamonds here!
-
-There is an enormous ruby here!
-
-There are bars of silver here!
-
-There is a Persian rug spread out on the floor!
-
-There is a large sparkling nugget of gold here!
-
-A precious jade necklace has been dropped here!
-
-There is precious jewelry here!
-
-> downstream
-
-The stream flows out through a pair of 1 foot diameter sewer pipes.
-It would be advisable to use the exit.
-
-You are inside a building, a well house for a large spring.
-
-There is a richly-carved ebony statuette here!
-
-There is an emerald here the size of a plover's egg!
-
-There is a jewel-encrusted trident here!
-
-There is a platinum pyramid here, 8 inches on a side!
-
-There are diamonds here!
-
-There is an enormous ruby here!
-
-There are bars of silver here!
-
-There is a Persian rug spread out on the floor!
-
-There is a large sparkling nugget of gold here!
-
-A precious jade necklace has been dropped here!
-
-There is precious jewelry here!
-
-> plugh
-
->>Foof!<<
-
-It is now pitch dark.  If you proceed you will likely fall into a pit.
-
-> on lamp
-
-Your lamp is now on.
-
-You are in a large room, with a passage to the south, a passage to the
-west, and a wall of broken rock to the east.  There is a large "Y2" on
-a rock in the room's center.
-
-> w
-
-You're at a low window overlooking a huge pit, which extends up out of
-sight.  A floor is indistinctly visible over 50 feet below.  Traces of
-white mist cover the floor of the pit, becoming thicker to the right.
-Marks in the dust around the window would seem to indicate that
-someone has been here recently.  Directly across the pit from you and
-25 feet away there is a similar window looking into a lighted room.  A
-shadowy figure can be seen there peering back at you.
-
-The shadowy figure seems to be trying to attract your attention.
-
-> e
-
-You're at "Y2".
-
-> s
-
-You're in n/s passage above e/w passage.
-
-> s
-
-You're in Hall of Mt King.
-
-> e
-
-You're in Hall of Mists.
-
-There is a little axe here.
-
-Rough stone steps lead up the dome.
-
-> take axe
-
-OK
-
-> listen
-
-The wind whistles coldly past your ears.
-
-> score
-
-You have garnered 207 out of a possible 430 points, using 413 turns.
-
-> inven
-
-You are currently holding the following:
-Brass lantern
-Dwarf's axe
-
-> waste 2443
-
-Game limit is now 27
-
-You're in Hall of Mists.
-
-Rough stone steps lead up the dome.
-
-> z
-
-Your lamp is getting dim, and you're out of spare batteries.  You'd
-best start wrapping this up.
-
 OK
 
-
-You scored 207 out of a possible 430, using 416 turns.
+You scored 223 out of a possible 430, using 303 turns.
 
 You may now consider yourself a "Seasoned Adventurer".
 
-To achieve the next higher rating, you need 44 more points.
+To achieve the next higher rating, you need 28 more points.
diff --git a/tests/bigfail.log b/tests/bigfail.log
index a839f1c..ae13163 100644
--- a/tests/bigfail.log
+++ b/tests/bigfail.log
@@ -1,4 +1,6 @@
 ## Test many nonlethal failure conditions
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # See comments in this log
 n
 seed 1838473132
@@ -310,141 +312,5 @@ sw
 free bear
 take bear
 sw
-yes
-inven
-out
-take lamp
-light lamp
-in
-plugh
-s
-d
-bedquilt
-n
-sw
-up
-over
-feed bear
-attack bear
-# We'll need these when the game times out
-take coins
-take axe
-# Back to fissure to vanish the bridge and then test OVER
-sw
-d
-se
-se
-ne
-e
-up
-e
-up
-s
-up
-w
-take rod
-wave rod
-across
-# Next, buy batteries but don't take them.
-wave rod
-across
-w
-w
-w
-s
-s
-sw
-se
-s
-s
-drop coins
-look
-n
-z
-z
-z
-z
-# Battery warning happens here.
-s
-take batteries
-# We now have 2500 more turns of life. Into the maze...
-n
-# Show that trying to back up in the maze fails
-back
-n
-nw
-d
-# Out of maze. Drink where nothing is eligible.
-drink
-e
-e
-# PARALLEL1 coverage
-n
-# If we go to hall of mists we'll meet a killer dwarf with the drop on us
-#e
-#e
-w
-w
-n
-e
-d
-e
-u
-throw axe
-d
-n
-d
-# Coverage of LOC_SMALLPIT and LOC_SMALLPITBRINK
-e
-d
-listen
-u
-w
-# Coverage of LOC_THREEJUNCTION, LOC_WINDOW2, LOC_SECRET2, LOC_TOPSTALACTITE,
-# LOC_NECKBROKE. Only accessible via stalactite from big maze or by random
-# exit from Bedquilt.
-bedquilt
-z
-z
-z
-n
-n
 n
-n
-# In secret canyon
-w
-n
-w
-s
-# LOC_TOPSTALACTITE
-s
-n
-s
-n
-n
-n
-jump
-y
-# Reincarnation, cover LOC_SEWER
-out
-take lamp
-in
-downstream
-plugh
-on lamp
-# Cover WINDOW1
-w
-e
-# Retrieve axe
-s
-s
-e
-take axe
-listen
-# At Hall of Mists
-score
-inven
-# Timewarp forward to test exhaustion of replacement batteries
-waste 2443
-z
-# MISSING_BATTERIES is uttered
+quit
diff --git a/tests/birdsnakewake.chk b/tests/birdsnakewake.chk
index 68f99d4..361cbf7 100644
--- a/tests/birdsnakewake.chk
+++ b/tests/birdsnakewake.chk
@@ -2930,7 +2930,7 @@ OK
 
 > take bird
 
-OK
+You are already carrying it!
 
 > free bird
 
diff --git a/tests/birdsnakewake.log b/tests/birdsnakewake.log
index 0d64d15..8c2d514 100644
--- a/tests/birdsnakewake.log
+++ b/tests/birdsnakewake.log
@@ -1,4 +1,6 @@
 ## Attempt to kill snake with bird in the endgame
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
diff --git a/tests/birdweight.chk b/tests/birdweight.chk
index 0df99e6..24f0904 100644
--- a/tests/birdweight.chk
+++ b/tests/birdweight.chk
@@ -456,7 +456,7 @@ attack.  He seems almost amused by your puny effort.
 
 OK
 
-
+> 
 You scored 61 out of a possible 430, using 81 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/birdweight.log b/tests/birdweight.log
index bc07eb6..216979b 100644
--- a/tests/birdweight.log
+++ b/tests/birdweight.log
@@ -1,5 +1,8 @@
 ## Verify that the bird is weightless in inventory
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # Checks fix for GitLab issue #40
+#NOCOMPARE Bird was not weightless in cage in advent430 so this test is invalid.
 n
 #seed 687800971
 seed 976729036
diff --git a/tests/boulder2.chk b/tests/boulder2.chk
index cdd7dbb..87aee68 100644
--- a/tests/boulder2.chk
+++ b/tests/boulder2.chk
@@ -984,7 +984,7 @@ There is a huge beanstalk growing out of the west pit up to the hole.
 You are at the bottom of the eastern pit in the Twopit Room.  There is
 a small pool of oil in one corner of the pit.
 
-> g oil
+> get oil
 
 Your bottle is now full of oil.
 
@@ -1351,7 +1351,7 @@ You're in Giant Room.
 
 There is a large nest here, full of golden eggs!
 
-> g
+> get
 
 OK
 
@@ -1479,7 +1479,7 @@ You're in Chamber of Boulders.
 
 There are rare spices here!
 
-
+> 
 You scored 119 out of a possible 430, using 238 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/boulder2.log b/tests/boulder2.log
index ad4acd4..886e0b9 100644
--- a/tests/boulder2.log
+++ b/tests/boulder2.log
@@ -1,4 +1,6 @@
 ## Coverage of LOC_BOULDERS2.short
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
@@ -156,7 +158,7 @@ u
 drop appen
 e
 d
-g oil
+get oil
 u
 w
 d
@@ -220,7 +222,7 @@ w
 d
 climb
 w
-g
+get
 n
 take bottl
 n
@@ -239,4 +241,4 @@ fork
 ne
 e
 out
-e
\ No newline at end of file
+e
diff --git a/tests/breakmirror.chk b/tests/breakmirror.chk
index 2581648..faf0008 100644
--- a/tests/breakmirror.chk
+++ b/tests/breakmirror.chk
@@ -2934,14 +2934,14 @@ Huh?
 
 Huh?
 
-> unlock oyster
-
-I advise you to put down the oyster before opening it.  >WRENCH!<
-
 > drop oyster
 
 OK
 
+> unlock oyster
+
+You don't have anything strong enough to open the oyster.
+
 > take oyster
 
 OK
diff --git a/tests/breakmirror.log b/tests/breakmirror.log
index 12b14e8..ba73337 100644
--- a/tests/breakmirror.log
+++ b/tests/breakmirror.log
@@ -1,4 +1,6 @@
 ## Break the mirror in endgame and die
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
@@ -467,14 +469,16 @@ e
 e
 cave
 e
-# Everything to here is from endgame428
+# Everything to here is from endgame428,
+# except we drop the oyster before trying
+# to unlock it rather than after.
 attack
 take oyster
 find oyster
 lock
 lock oyster
-unlock oyster
 drop oyster
+unlock oyster
 take oyster
 read oyster
 y
@@ -482,4 +486,3 @@ sw
 attack bird
 find bird
 break mirror
-
diff --git a/tests/carrybird.chk b/tests/carrybird.chk
index 7f3b931..5b4b1de 100644
--- a/tests/carrybird.chk
+++ b/tests/carrybird.chk
@@ -51,10 +51,6 @@ has scrawled, "MAGIC WORD XYZZY".
 
 A three foot black rod with a rusty star on an end lies nearby.
 
-> eat grate
-
-I see no grate here.
-
 > w
 
 You are in an awkward sloping east/west canyon.
@@ -75,8 +71,8 @@ You can catch the bird, but you cannot carry it.
 
 The little bird is now dead.  Its body disappears.
 
-
-You scored 32 out of a possible 430, using 10 turns.
+> 
+You scored 32 out of a possible 430, using 9 turns.
 
 You are obviously a rank amateur.  Better luck next time.
 
diff --git a/tests/carrybird.log b/tests/carrybird.log
index 5f79548..296a825 100644
--- a/tests/carrybird.log
+++ b/tests/carrybird.log
@@ -1,4 +1,6 @@
 ## Try to carry bird without cage, then kill bird
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1071883378
 in
@@ -6,9 +8,8 @@ take lamp
 rub lamp
 xyzzy
 on
-eat grate
 w
 w
 take bird
 # test intransitive attack on bird
-attack
\ No newline at end of file
+attack
diff --git a/tests/carryfreebird.chk b/tests/carryfreebird.chk
index dcaf64b..870ea4b 100644
--- a/tests/carryfreebird.chk
+++ b/tests/carryfreebird.chk
@@ -327,7 +327,7 @@ The bird eyes you suspiciously and flutters away.  A moment later you
 feel something wet land on your head, but upon looking up you can see
 no sign of the culprit.
 
-
+> 
 You scored 113 out of a possible 430, using 57 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/carryfreebird.log b/tests/carryfreebird.log
index 0c81742..4867b05 100644
--- a/tests/carryfreebird.log
+++ b/tests/carryfreebird.log
@@ -1,4 +1,6 @@
 ## Try to carry the bird after freeing it instead of listening
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1495951709
 attack
diff --git a/tests/cheatresume.chk b/tests/cheatresume.chk
index e11a776..a56a78b 100644
--- a/tests/cheatresume.chk
+++ b/tests/cheatresume.chk
@@ -13,14 +13,15 @@ You are standing at the end of a road before a small brick building.
 Around you is a forest.  A small stream flows out of the building and
 down a gully.
 
-
+> 
 Now let's see you do it without suspending in mid-Adventure.
 
 You scored 9031 out of a possible 430, using 0 turns.
 
-'Adventuredom stands in awe -- you have now joined the ranks of the
+Adventuredom stands in awe -- you have now joined the ranks of the
        W O R L D   C H A M P I O N   A D V E N T U R E R S !
 It may interest you to know that the Dungeon-Master himself has, to
-my knowledge, never achieved this threshold in fewer than 330 turns.'
+my knowledge, never achieved this threshold in fewer than 330 turns.
 
-To achieve the next higher rating, you need 969 more points.
+To achieve the next higher rating would be a neat trick!
+Congratulations!!
diff --git a/tests/cheatresume.log b/tests/cheatresume.log
index 45d8df2..1a0e60e 100644
--- a/tests/cheatresume.log
+++ b/tests/cheatresume.log
@@ -1,4 +1,7 @@
 ## Resume from absurd save file with numdie = -900
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE Can't compare to advent430 due to version skew
 n
 resume
 cheat_numdie.adv
diff --git a/tests/cheatresume2.chk b/tests/cheatresume2.chk
index 086e3d8..af3648c 100644
--- a/tests/cheatresume2.chk
+++ b/tests/cheatresume2.chk
@@ -13,12 +13,9 @@ You are standing at the end of a road before a small brick building.
 Around you is a forest.  A small stream flows out of the building and
 down a gully.
 
-
+> 
 Now let's see you do it without suspending in mid-Adventure.
 
 You scored 10031 out of a possible 430, using 0 turns.
 
 You just went off my scale!!
-
-To achieve the next higher rating would be a neat trick!
-Congratulations!!
diff --git a/tests/cheatresume2.log b/tests/cheatresume2.log
index 614c692..d5d8eee 100644
--- a/tests/cheatresume2.log
+++ b/tests/cheatresume2.log
@@ -1,5 +1,8 @@
 ## Resume from absurd save file with numdie = -1000
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # generating "off my scale" score threshold message
+#NOCOMPARE Can't compare to advent430 due to version skew
 n
 resume
 cheat_numdie1000.adv
diff --git a/tests/coverage_dungeon.py b/tests/coverage_dungeon.py
index 8bb1c46..2b4c515 100755
--- a/tests/coverage_dungeon.py
+++ b/tests/coverage_dungeon.py
@@ -1,4 +1,6 @@
 #!/usr/bin/env python3
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 """
 This is the open-adventure dungeon text coverage report generator. It
 consumes a YAML description of the dungeon and determines whether the
@@ -7,11 +9,14 @@ various strings contained are present within the test check files.
 The default HTML output is appropriate for use with Gitlab CI.
 You can override it with a command-line argument.
 
-The DANGLING list is for actions that should be considered always found
-even if the checkfile search doesn't find them. Typically this will because
-they emit a templated message that can't be regression-tested by equality.
+The DANGLING lists are for actions and messages that should be
+considered always found even if the checkfile search doesn't find them.
+Typically this will because an action emit a templated message that
+can't be regression-tested by equality.
 """
 
+# pylint: disable=consider-using-f-string,line-too-long,invalid-name,missing-function-docstring,redefined-outer-name
+
 import os
 import sys
 import re
@@ -21,7 +26,8 @@ TEST_DIR = "."
 YAML_PATH = "../adventure.yaml"
 HTML_TEMPLATE_PATH = "../templates/coverage_dungeon.html.tpl"
 DEFAULT_HTML_OUTPUT_PATH = "../coverage/adventure.yaml.html"
-DANGLING = ["ACT_VERSION"]
+DANGLING_ACTIONS = ["ACT_VERSION"]
+DANGLING_MESSAGES = ["SAVERESUME_DISABLED"]
 
 STDOUT_REPORT_CATEGORY = "  {name:.<19}: {percent:5.1f}% covered ({covered} of {total})\n"
 
@@ -95,7 +101,7 @@ def obj_coverage(objects, text, report):
 
 def loc_coverage(locations, text, report):
     # locations have a long and a short description, that each have to
-    # be checked seperately
+    # be checked separately
     for name, loc in locations:
         desc = loc["description"]
         if name not in report["messages"]:
@@ -143,7 +149,7 @@ def threshold_coverage(classes, text, report):
     # property
     for name, item in enumerate(classes):
         if name not in report["messages"]:
-            report["messages"][name] = {"covered" : "False"}
+            report["messages"][name] = {"covered" : False}
             report["total"] += 1
         if not report["messages"][name]["covered"] and search(item["message"], text):
             report["messages"][name]["covered"] = True
@@ -154,7 +160,7 @@ def arb_coverage(arb_msgs, text, report):
         if name not in report["messages"]:
             report["messages"][name] = {"covered" : False}
             report["total"] += 1
-        if not report["messages"][name]["covered"] and search(message, text):
+        if not report["messages"][name]["covered"] and (search(message, text) or name in DANGLING_MESSAGES):
             report["messages"][name]["covered"] = True
             report["covered"] += 1
 
@@ -164,12 +170,12 @@ def actions_coverage(items, text, report):
         if name not in report["messages"]:
             report["messages"][name] = {"covered" : False}
             report["total"] += 1
-        if not report["messages"][name]["covered"] and (search(item["message"], text) or name in DANGLING):
+        if not report["messages"][name]["covered"] and (search(item["message"], text) or name in DANGLING_ACTIONS):
             report["messages"][name]["covered"] = True
             report["covered"] += 1
 
 def coverage_report(db, check_file_contents):
-    # Create report for each catagory, including total items,  number of items
+    # Create report for each category, including total items,  number of items
     # covered, and a list of the covered messages
     report = {}
     for name in db.keys():
@@ -197,7 +203,7 @@ def coverage_report(db, check_file_contents):
 if __name__ == "__main__":
     # load DB
     try:
-        with open(YAML_PATH, "r") as f:
+        with open(YAML_PATH, "r", encoding='ascii', errors='surrogateescape') as f:
             db = yaml.safe_load(f)
     except IOError as e:
         print('ERROR: could not load %s (%s)' % (YAML_PATH, e.strerror))
@@ -207,7 +213,7 @@ if __name__ == "__main__":
     check_file_contents = []
     for filename in os.listdir(TEST_DIR):
         if filename.endswith(".chk"):
-            with open(filename, "r") as f:
+            with open(filename, "r", encoding='ascii', errors='surrogateescape') as f:
                 check_file_contents.append(f.read())
 
     # run coverage analysis report on dungeon database
@@ -254,7 +260,7 @@ if __name__ == "__main__":
 
     # render HTML report
     try:
-        with open(HTML_TEMPLATE_PATH, "r") as f:
+        with open(HTML_TEMPLATE_PATH, "r", encoding='ascii', errors='surrogateescape') as f:
             # read in HTML template
             html_template = f.read()
     except IOError as e:
@@ -263,7 +269,7 @@ if __name__ == "__main__":
 
     # parse template with report and write it out
     try:
-        with open(html_output_path, "w") as f:
+        with open(html_output_path, "w", encoding='ascii', errors='surrogateescape') as f:
             f.write(html_template.format(categories=categories_html, summary=summary_html))
     except IOError as e:
         print('ERROR: writing HTML report failed ({})'.format(e.strerror))
diff --git a/tests/death-jump.log b/tests/death-jump.log
index 3c877f0..835c02c 100644
--- a/tests/death-jump.log
+++ b/tests/death-jump.log
@@ -1,4 +1,6 @@
 ## Jump into a pit and die, refuse reincarnation
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1495774850
 in
diff --git a/tests/defeat.log b/tests/defeat.log
index c42430a..b46767d 100644
--- a/tests/defeat.log
+++ b/tests/defeat.log
@@ -1,4 +1,6 @@
 ## Last-minute defeat, with lava. Also tests vase drop before pillow.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56
 n
 seed 1838473132
diff --git a/tests/domefail.chk b/tests/domefail.chk
index 000995b..961b8c5 100644
--- a/tests/domefail.chk
+++ b/tests/domefail.chk
@@ -166,7 +166,7 @@ The dome is unclimbable.
 
 You're in Hall of Mists.
 
-
+> 
 You scored 63 out of a possible 430, using 24 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/domefail.log b/tests/domefail.log
index df46939..c832fb0 100644
--- a/tests/domefail.log
+++ b/tests/domefail.log
@@ -1,4 +1,6 @@
 ## Take nugget and fail to climb to the dome
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
diff --git a/tests/dragon_secret5.chk b/tests/dragon_secret5.chk
index 1d5e121..b469f27 100644
--- a/tests/dragon_secret5.chk
+++ b/tests/dragon_secret5.chk
@@ -246,7 +246,7 @@ There is a Persian rug spread out on the floor!
 
 The blood-specked body of a huge green dead dragon lies to one side.
 
-
+> 
 You scored 65 out of a possible 430, using 32 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/dragon_secret5.log b/tests/dragon_secret5.log
index 15f3668..a630ccc 100644
--- a/tests/dragon_secret5.log
+++ b/tests/dragon_secret5.log
@@ -1,4 +1,6 @@
 ## Check that dead dragon actually moves its location (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 18084731
 in
diff --git a/tests/dropcagedbird.chk b/tests/dropcagedbird.chk
index b5c64e6..5f382a3 100644
--- a/tests/dropcagedbird.chk
+++ b/tests/dropcagedbird.chk
@@ -150,7 +150,7 @@ A huge green fierce snake bars the way!
 
 There's nothing here it wants to eat (except perhaps you).
 
-
+> 
 You scored 59 out of a possible 430, using 25 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/dropcagedbird.log b/tests/dropcagedbird.log
index ba90580..2ca0c99 100644
--- a/tests/dropcagedbird.log
+++ b/tests/dropcagedbird.log
@@ -1,4 +1,6 @@
 ## Try to carry the bird after freeing it instead of listening
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1495951709
 in
@@ -25,4 +27,4 @@ take bird
 drop cage
 d
 d
-feed snake
\ No newline at end of file
+feed snake
diff --git a/tests/drown.log b/tests/drown.log
index b5ebf27..257aeea 100644
--- a/tests/drown.log
+++ b/tests/drown.log
@@ -1,4 +1,6 @@
 ## Speak a magic word at an inopportune time and drown.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56
 n
 seed 1838473132
diff --git a/tests/dwarf.log b/tests/dwarf.log
index 3bb0d4b..36a225b 100644
--- a/tests/dwarf.log
+++ b/tests/dwarf.log
@@ -1,4 +1,6 @@
 ## In which the dwarf kills you
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1494912171
 in
diff --git a/tests/dwarf_alternative.chk b/tests/dwarf_alternative.chk
index 5fcaf06..1dae06b 100644
--- a/tests/dwarf_alternative.chk
+++ b/tests/dwarf_alternative.chk
@@ -58,3 +58,12 @@ Oh dear, you seem to have gotten yourself killed.  I might be able to
 help you out, but I've never really done this before.  Do you want me
 to try to reincarnate you?
 
+> n
+
+OK
+
+You scored 51 out of a possible 430, using 7 turns.
+
+Your score qualifies you as a novice class adventurer.
+
+To achieve the next higher rating, you need 70 more points.
diff --git a/tests/dwarf_alternative.log b/tests/dwarf_alternative.log
index 69a0619..af0a9c8 100644
--- a/tests/dwarf_alternative.log
+++ b/tests/dwarf_alternative.log
@@ -1,4 +1,6 @@
 ## Check that dwarf spawns in alternative location (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 383847
 in
@@ -8,3 +10,4 @@ w
 w
 d
 d
+n
diff --git a/tests/eggs_done.chk b/tests/eggs_done.chk
index baa766f..4e85042 100644
--- a/tests/eggs_done.chk
+++ b/tests/eggs_done.chk
@@ -1167,7 +1167,7 @@ You're in Giant Room.
 
 There is a large nest here, full of golden eggs!
 
-> g egg
+> take egg
 
 OK
 
@@ -1223,7 +1223,7 @@ Wicker cage
 Black rod
 Small bottle
 
-
+> 
 You scored 77 out of a possible 430, using 190 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/eggs_done.log b/tests/eggs_done.log
index 1d600f0..451d3e5 100644
--- a/tests/eggs_done.log
+++ b/tests/eggs_done.log
@@ -1,4 +1,6 @@
 ## Be done with Giant Room and eggs (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
@@ -184,11 +186,11 @@ w
 d
 climb
 w
-g egg
+take egg
 n
 fee
 fie
 foe
 foo
 look
-inven
\ No newline at end of file
+inven
diff --git a/tests/eggs_vanish.chk b/tests/eggs_vanish.chk
index 5f84bfc..256ac5e 100644
--- a/tests/eggs_vanish.chk
+++ b/tests/eggs_vanish.chk
@@ -399,7 +399,7 @@ the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic].
 
 There is a large nest here, full of golden eggs!
 
-> g
+> take
 
 OK
 
@@ -435,7 +435,7 @@ There is a large nest here, full of golden eggs!
 
 The passage here is blocked by a recent cave-in.
 
-
+> 
 You scored 67 out of a possible 430, using 66 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/eggs_vanish.log b/tests/eggs_vanish.log
index 452335d..7c5f406 100644
--- a/tests/eggs_vanish.log
+++ b/tests/eggs_vanish.log
@@ -1,4 +1,6 @@
 ## Vanishing eggs in Giant Room (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
@@ -59,7 +61,7 @@ d
 water plant
 climb
 w
-g
+take
 n
 fee
 fie
@@ -67,4 +69,4 @@ foe
 foo
 # go south, east to arrive at LOC_CAVEIN for coverage
 s
-e
\ No newline at end of file
+e
diff --git a/tests/endgame428.log b/tests/endgame428.log
index 8df0238..e86c92d 100644
--- a/tests/endgame428.log
+++ b/tests/endgame428.log
@@ -1,4 +1,6 @@
 ## 428-point walkthrough
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56
 n
 seed 1838473132
diff --git a/tests/endobjects.chk b/tests/endobjects.chk
index 1f06db5..42132d3 100644
--- a/tests/endobjects.chk
+++ b/tests/endobjects.chk
@@ -2435,11 +2435,12 @@ OK
 
 You are currently holding the following:
 Wicker cage
+Little bird in cage
 Small bottle
 
 > get bird
 
-OK
+You are already carrying it!
 
 > inven
 
diff --git a/tests/endobjects.log b/tests/endobjects.log
index e532df0..1165360 100644
--- a/tests/endobjects.log
+++ b/tests/endobjects.log
@@ -1,5 +1,8 @@
 ### Check that water is unavailable in endgame
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # Addresses GitLab issue #55: in endgame, some object starting states are incorrect
+#NOCOMPARE Bird was not weightless in cage in advent430, this test depends on that.
 no
 seed 11247848
 no
diff --git a/tests/fail_hint_maze.chk b/tests/fail_hint_maze.chk
index 9973218..46b0aa7 100644
--- a/tests/fail_hint_maze.chk
+++ b/tests/fail_hint_maze.chk
@@ -436,7 +436,7 @@ OK
 
 OK
 
-
+> 
 You scored 59 out of a possible 430, using 93 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/fail_hint_maze.log b/tests/fail_hint_maze.log
index d458561..409286c 100644
--- a/tests/fail_hint_maze.log
+++ b/tests/fail_hint_maze.log
@@ -1,4 +1,6 @@
 ## Fail to get maze hint by being empty-handed (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 25508795
 in
diff --git a/tests/fail_hint_ogre.chk b/tests/fail_hint_ogre.chk
index 71a9d72..4d300b7 100644
--- a/tests/fail_hint_ogre.chk
+++ b/tests/fail_hint_ogre.chk
@@ -1638,7 +1638,7 @@ OK
 
 OK
 
-
+> 
 You scored 77 out of a possible 430, using 263 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/fail_hint_ogre.log b/tests/fail_hint_ogre.log
index c26ecbb..01af475 100644
--- a/tests/fail_hint_ogre.log
+++ b/tests/fail_hint_ogre.log
@@ -1,4 +1,7 @@
 ## Qualify for ogre hint but fail due to dwarves dead (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE Fails due uninteresting difference in whitespace process. 
 n
 seed 1838473132
 in
diff --git a/tests/fail_hint_ogre2.chk b/tests/fail_hint_ogre2.chk
index 28b673e..3437b22 100644
--- a/tests/fail_hint_ogre2.chk
+++ b/tests/fail_hint_ogre2.chk
@@ -394,7 +394,7 @@ You are in a large chamber with passages to the west and north.
 
 A formidable ogre bars the northern exit.
 
-
+> 
 You scored 63 out of a possible 430, using 56 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/fail_hint_ogre2.log b/tests/fail_hint_ogre2.log
index 4961479..9b01049 100644
--- a/tests/fail_hint_ogre2.log
+++ b/tests/fail_hint_ogre2.log
@@ -1,4 +1,6 @@
 ## Qualify for ogre hint but fail due to nearby dwarf (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 25508795
 in
diff --git a/tests/fail_hint_woods.chk b/tests/fail_hint_woods.chk
index 990cf8e..ca5ac5e 100644
--- a/tests/fail_hint_woods.chk
+++ b/tests/fail_hint_woods.chk
@@ -109,7 +109,7 @@ OK
 
 OK
 
-
+> 
 You scored 32 out of a possible 430, using 25 turns.
 
 You are obviously a rank amateur.  Better luck next time.
diff --git a/tests/fail_hint_woods.log b/tests/fail_hint_woods.log
index 5c37435..69d075e 100644
--- a/tests/fail_hint_woods.log
+++ b/tests/fail_hint_woods.log
@@ -1,4 +1,6 @@
 ## Fail getting wood hint by finding appendage (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 n
 z
@@ -24,4 +26,4 @@ z
 z
 z
 z
-z
\ No newline at end of file
+z
diff --git a/tests/fillfail.chk b/tests/fillfail.chk
index fd3d096..11f58eb 100644
--- a/tests/fillfail.chk
+++ b/tests/fillfail.chk
@@ -57,7 +57,7 @@ You can't fill that.
 
 Your bottle is already full.
 
-
+> 
 You scored 32 out of a possible 430, using 10 turns.
 
 You are obviously a rank amateur.  Better luck next time.
diff --git a/tests/fillfail.log b/tests/fillfail.log
index afb125f..543bc27 100644
--- a/tests/fillfail.log
+++ b/tests/fillfail.log
@@ -1,4 +1,6 @@
 ## Attempt to fill lamp, attempt to fill bottle with no source
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 in
 carry lamp
diff --git a/tests/fillvase.chk b/tests/fillvase.chk
index 5d8c889..cbbeea4 100644
--- a/tests/fillvase.chk
+++ b/tests/fillvase.chk
@@ -1463,7 +1463,7 @@ A small velvet pillow lies on the ground.
 
 You can't be serious!
 
-
+> 
 You scored 191 out of a possible 430, using 241 turns.
 
 You may now consider yourself a "Seasoned Adventurer".
diff --git a/tests/fillvase.log b/tests/fillvase.log
index 8414f14..da776b9 100644
--- a/tests/fillvase.log
+++ b/tests/fillvase.log
@@ -1,4 +1,6 @@
 ## Fill the vase
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # Arthur O'Dwyer <arthur.j.odwyer@gmail.com> writes:
 #
 # (4) Lastly, here's a test case for you! Go get the VASE; then get the
diff --git a/tests/flyback.chk b/tests/flyback.chk
index 2d8750e..04b658c 100644
--- a/tests/flyback.chk
+++ b/tests/flyback.chk
@@ -2039,8 +2039,6 @@ There is a Persian rug here, hovering in mid-air!
 A brilliant blue star sapphire is here!
 
 > 
-
-
 You scored 257 out of a possible 430, using 337 turns.
 
 You have reached "Junior Master" status.
diff --git a/tests/flyback.log b/tests/flyback.log
index b849cc8..3c34df4 100644
--- a/tests/flyback.log
+++ b/tests/flyback.log
@@ -1,4 +1,7 @@
-## Test fix for issue #51: rug flying is broken
+## Test fix for issue 51: rug flying is broken
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE Behavior differs due to a bug fix.
 n
 seed 1838473132
 in
@@ -340,4 +343,3 @@ drop emerald
 fly rug
 fly rug
 fly rug
-
diff --git a/tests/footslip.chk b/tests/footslip.chk
index ef2f595..a9f28d3 100644
--- a/tests/footslip.chk
+++ b/tests/footslip.chk
@@ -796,7 +796,7 @@ There is food here.
 
 > 
 
-
+> 
 You scored 61 out of a possible 430, using 121 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/footslip.log b/tests/footslip.log
index ad02244..4f1d7cd 100644
--- a/tests/footslip.log
+++ b/tests/footslip.log
@@ -1,4 +1,6 @@
 ## Coverage of LOC_FOOTSLIP
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
diff --git a/tests/gemstates.chk b/tests/gemstates.chk
index db58aa4..8739f93 100644
--- a/tests/gemstates.chk
+++ b/tests/gemstates.chk
@@ -2145,7 +2145,7 @@ There is a ruby resting in a small cavity in the rock!
 
 There is a Persian rug spread out on the floor!
 
-
+> 
 You scored 271 out of a possible 430, using 365 turns.
 
 You have reached "Junior Master" status.
diff --git a/tests/gemstates.log b/tests/gemstates.log
index ea49416..6ac1547 100644
--- a/tests/gemstates.log
+++ b/tests/gemstates.log
@@ -1,4 +1,6 @@
 ## Observe amber, ruby, sapphire after state change
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1635997320
 in
diff --git a/tests/goback.chk b/tests/goback.chk
index 27d0cb8..fb6eb0f 100644
--- a/tests/goback.chk
+++ b/tests/goback.chk
@@ -2527,7 +2527,7 @@ best start wrapping this up.
 
 OK
 
-
+> 
 You scored 207 out of a possible 430, using 413 turns.
 
 You may now consider yourself a "Seasoned Adventurer".
diff --git a/tests/goback.log b/tests/goback.log
index 2915836..fcc06c2 100644
--- a/tests/goback.log
+++ b/tests/goback.log
@@ -1,6 +1,9 @@
 ## Test many nonlethal failure conditions
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # This variant elicits the prompt to go back for batteries
 # See comments in this log
+#NOCOMPARE Relies on "waste"
 n
 seed 1838473132
 in
diff --git a/tests/hint_dark.chk b/tests/hint_dark.chk
index cee6051..1a95bf8 100644
--- a/tests/hint_dark.chk
+++ b/tests/hint_dark.chk
@@ -150,7 +150,7 @@ There is a way to explore that region without having to worry about
 falling into a pit.  None of the objects available is immediately
 useful in discovering the secret.
 
-
+> 
 You scored 54 out of a possible 430, using 27 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/hint_dark.log b/tests/hint_dark.log
index b522b90..a45074a 100644
--- a/tests/hint_dark.log
+++ b/tests/hint_dark.log
@@ -1,4 +1,6 @@
 ## Elicit hint for dealing with plugh room and darkness (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1495951709
 in
@@ -29,4 +31,4 @@ z
 z
 z
 y
-y
\ No newline at end of file
+y
diff --git a/tests/hint_grate.chk b/tests/hint_grate.chk
index 652b639..fa7d80d 100644
--- a/tests/hint_grate.chk
+++ b/tests/hint_grate.chk
@@ -83,7 +83,7 @@ The grate is very solid and has a hardened steel lock.  You cannot
 enter without a key, and there are no keys nearby.  I would recommend
 looking elsewhere for the keys.
 
-
+> 
 You scored 30 out of a possible 430, using 10 turns.
 
 You are obviously a rank amateur.  Better luck next time.
diff --git a/tests/hint_grate.log b/tests/hint_grate.log
index e7ddd73..8af49de 100644
--- a/tests/hint_grate.log
+++ b/tests/hint_grate.log
@@ -1,4 +1,6 @@
 ## Elicit hint for dealing with grate
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1495774850
 in
diff --git a/tests/hint_jade.chk b/tests/hint_jade.chk
index f16accf..e8d9f81 100644
--- a/tests/hint_jade.chk
+++ b/tests/hint_jade.chk
@@ -962,7 +962,7 @@ There is a huge beanstalk growing out of the west pit up to the hole.
 You are at the bottom of the eastern pit in the Twopit Room.  There is
 a small pool of oil in one corner of the pit.
 
-> g oil
+> get oil
 
 Your bottle is now full of oil.
 
@@ -1325,7 +1325,7 @@ You're in Giant Room.
 
 There is a large nest here, full of golden eggs!
 
-> g
+> get
 
 OK
 
@@ -1424,7 +1424,8 @@ down a gentle slope.  The main corridor enters from the west.
 
 You are being followed by a very large, tame bear.
 
-You are walking along a gently sloping north/south passage lined with oddly shaped limestone formations.
+You are walking along a gently sloping north/south passage lined with
+oddly shaped limestone formations.
 
 > fork
 
@@ -1545,7 +1546,7 @@ There is a huge beanstalk growing out of the west pit up to the hole.
 
 You're in east pit.
 
-> g oil
+> get oil
 
 Your bottle is now full of oil.
 
@@ -1848,7 +1849,7 @@ Do you want the hint?
 Once you've found all the other treasures, it is no longer possible to
 locate the one you're now missing.
 
-
+> 
 You scored 91 out of a possible 430, using 297 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/hint_jade.log b/tests/hint_jade.log
index d5550d0..904aa92 100644
--- a/tests/hint_jade.log
+++ b/tests/hint_jade.log
@@ -1,4 +1,6 @@
 ## Elicit hint for getting the jade (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
@@ -151,7 +153,7 @@ u
 drop appen
 e
 d
-g oil
+get oil
 u
 w
 d
@@ -214,7 +216,7 @@ w
 d
 climb
 w
-g
+get
 n
 take bottl
 n
@@ -249,7 +251,7 @@ se
 se
 w
 d
-g oil
+get oil
 u
 w
 w
diff --git a/tests/hint_snake.chk b/tests/hint_snake.chk
index 78ca80f..d5a1c44 100644
--- a/tests/hint_snake.chk
+++ b/tests/hint_snake.chk
@@ -192,7 +192,7 @@ You can't kill the snake, or drive it away, or avoid it, or anything
 like that.  There is a way to get by, but you don't have the necessary
 resources right now.
 
-
+> 
 You scored 55 out of a possible 430, using 25 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/hint_snake.log b/tests/hint_snake.log
index 9ffc302..76b719b 100644
--- a/tests/hint_snake.log
+++ b/tests/hint_snake.log
@@ -1,4 +1,6 @@
 ## Elicit hint for dealing with snake
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1951269982
 in
diff --git a/tests/hint_urn.chk b/tests/hint_urn.chk
index d51adc1..63b7542 100644
--- a/tests/hint_urn.chk
+++ b/tests/hint_urn.chk
@@ -74,7 +74,7 @@ Do you want the hint?
 This section is quite advanced.  Find the cave first.
 
 
-
+> 
 You scored 30 out of a possible 430, using 11 turns.
 
 You are obviously a rank amateur.  Better luck next time.
diff --git a/tests/hint_urn.log b/tests/hint_urn.log
index 8154e71..d12ceda 100644
--- a/tests/hint_urn.log
+++ b/tests/hint_urn.log
@@ -1,4 +1,7 @@
 ## Elicit hint for dealing with urn (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE Policy decision - no point in emulating advent430's extra \n here
 n
 seed 1495951709
 u
@@ -13,4 +16,4 @@ z
 z
 z
 y
-y
\ No newline at end of file
+y
diff --git a/tests/hint_witt.chk b/tests/hint_witt.chk
index 5afca9f..315f402 100644
--- a/tests/hint_witt.chk
+++ b/tests/hint_witt.chk
@@ -2430,7 +2430,7 @@ Do you want the hint?
 Don't go west.
 
 
-
+> 
 You scored 339 out of a possible 430, using 397 turns.
 
 Your score puts you in Master Adventurer Class C.
diff --git a/tests/hint_witt.log b/tests/hint_witt.log
index fd2a4f2..07e0785 100644
--- a/tests/hint_witt.log
+++ b/tests/hint_witt.log
@@ -1,4 +1,7 @@
 ## Hint for Witt's End
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE Policy decision - no point in emulating advent430's extra \n here
 n
 seed 1635997320
 in
@@ -400,4 +403,4 @@ n
 n
 n
 y
-y
\ No newline at end of file
+y
diff --git a/tests/illformed.chk b/tests/illformed.chk
index e18fbf9..925fc31 100644
--- a/tests/illformed.chk
+++ b/tests/illformed.chk
@@ -73,13 +73,13 @@ Sorry, but I no longer seem to remember how it was you got here.
 
 You're in front of building.
 
-> seed
+> waste
 
 This command requires a numeric argument.
 
 You're in front of building.
 
-> waste
+> seed
 
 This command requires a numeric argument.
 
@@ -126,22 +126,6 @@ There is a bottle of water here.
 
 Nothing happens.
 
-> say fee
-
-OK
-
-> say fie
-
-OK
-
-> say foe
-
-OK
-
-> say fum
-
-Nothing happens.
-
 > in
 
 I don't know in from out here.  Use compass points or name something
@@ -161,539 +145,9 @@ There is a bottle of water here.
 
 What do you want to do with the keys?
 
-> throw food
-
-You aren't carrying it!
-
-> nothing food
-
-OK
-
-> calm food
-
-I'm game.  Would you care to explain how?
-
-> walk food
-
-Where?
-
-> score food
-
-Huh?
-
-> foo food
-
-I don't know how.
-
-> brief food
-
-On what?
-
-> blast food
-
-Blasting requires dynamite.
-
-> find grate
-
-I can only tell you what you see as you move about and manipulate
-things.  I cannot tell you where remote things are.
-
-> light food
-
-I'm afraid I don't understand.
-
-> lock food
-
-I don't know how to lock or unlock such a thing.
-
-> unlock food
-
-I don't know how to lock or unlock such a thing.
-
-> extinguish food
-
-I'm afraid I don't understand.
-
-> suspend food
-
-Huh?
-
-> resume food
-
-Huh?
-
-> crawl
-
-Which way?
-
-You're inside building.
-
-There are some keys on the ground here.
-
-There is a shiny brass lamp nearby.
-
-There is food here.
-
-There is a bottle of water here.
-
-> out
-
-You're in front of building.
-
-> stream
-
-You are in a valley in the forest beside a stream tumbling along a
-rocky bed.
-
-> lock
-
-There is nothing here with a lock!
-
-> take water
-
-You have nothing in which to carry it.
-
-> blast
-
-Blasting requires dynamite.
-
-> building
-
-You're in front of building.
-
-> cave
-
-I don't know where the cave is, but hereabouts no stream can run on
-the surface for long.  I would try the stream.
-
-You're in front of building.
-
-> enter stream
-
-Your feet are now wet.
-
-> try three words
-
-Please stick to 1- and 2-word commands.
-
-> listen
-
-The stream is gurgling placidly.
-
-> carry
-
-Carry what?
-
-> forward
-
-I am unsure how you are facing.  Use compass points or nearby objects.
-
-You're in front of building.
-
-> eat
-
-Eat what?
-
-> drink
-
-You have taken a drink from the stream.  The water tastes strongly of
-minerals, but is not unpleasant.  It is extremely cold.
-
-> throw keys
-
-I see no keys here.
-
-> find keys
-
-I can only tell you what you see as you move about and manipulate
-things.  I cannot tell you where remote things are.
-
-> inven keys
-
-I can only tell you what you see as you move about and manipulate
-things.  I cannot tell you where remote things are.
-
-> nothing
-
-OK
-
-> in
-
-You're inside building.
-
-There are some keys on the ground here.
-
-There is a shiny brass lamp nearby.
-
-There is food here.
-
-There is a bottle of water here.
-
-> listen
-
-The stream is gurgling placidly.
-
-> find keys
-
-I believe what you want is right here with you.
-
-> unlock keys
-
-You can't unlock the keys.
-
-> find foo
-
-Nothing happens.
-
-> find bar
-
-Sorry, I don't know the word "bar".
-
-> carry
-
-Carry what?
-
-> blast
-
-Blasting requires dynamite.
-
-> take bottle
-
-OK
-
-> find bottle
-
-You are already carrying it!
-
-> drink water
-
-The bottle of water is now empty.
-
-> fill bottle
-
-Your bottle is now full of water.
-
-> throw axe
-
-I see no axe here.
-
-> throw knife
-
-I see no knife here.
-
-> lock
-
-There is nothing here with a lock!
-
-> unlock
-
-There is nothing here with a lock!
-
-> throw
-
-Throw what?
-
-> attack
-
-There is nothing here to attack.
-
-> unlock chain
-
-I see no chain here.
-
-> fill urn
-
-I see no urn here.
-
-> eat keys
-
-Don't be ridiculous!
-
-> discard keys
-
-You aren't carrying it!
-
-> drink keys
-
-Don't be ridiculous!
-
-> off keys
-
-I'm afraid I don't understand.
-
-> break keys
-
-It is beyond your power to do that.
-
-> wake keys
-
-Don't be ridiculous!
-
-> take keys
-
-OK
-
-> feed keys
-
-I'm game.  Would you care to explain how?
-
-> fly keys
-
-I'm game.  Would you care to explain how?
-
-> pour keys
-
-You can't pour that.
-
-> throw keys
-
-OK
-
-> foo up
-
-There is no way to go that direction.
-
-You are inside a building, a well house for a large spring.
-
-There are some keys on the ground here.
-
-There is a shiny brass lamp nearby.
-
-There is food here.
-
-> get
-
-Get what?
-
-> food
-
-OK
-
-> eat food
-
-Thank you, it was delicious!
-
-> drink blood
-
-I see no blood here.
-
-> drink keys
-
-Don't be ridiculous!
-
-> light keys
-
-I'm afraid I don't understand.
-
-> brief
-
-Okay, from now on I'll only describe a place in full the first time
-you come to it.  To get the full description, say "look".
-
-> frob grate
-
-Sorry, I don't know the word "frob".
-
-> read grate
-
-I see no grate here.
-
-> grate
-
-I don't know how to apply that word here.
-
-You're inside building.
-
-There are some keys on the ground here.
-
-There is a shiny brass lamp nearby.
-
-> pour bottle
-
-Your bottle is empty and the ground is wet.
-
-> fill bottle
-
-Your bottle is now full of water.
-
-> building
-
-I don't know how to apply that word here.
-
-You're inside building.
-
-There are some keys on the ground here.
-
-There is a shiny brass lamp nearby.
-
-> on
-
-Your lamp is now on.
-
-> pour bottle
-
-Your bottle is empty and the ground is wet.
-
-> xyzzy
-
->>Foof!<<
-
-It is now pitch dark.  If you proceed you will likely fall into a pit.
-
-> take rod
-
-OK
-
-> wave rod
-
-Nothing happens.
-
-> listen
-
-All is silent.
-
-> quit
-
-Do you really want to quit now?
-
-> n
-
-OK
-
-> read
-
-Read what?
-
-> look
-
-It is now pitch dark.  If you proceed you will likely fall into a pit.
-
-> l
-
-It is now pitch dark.  If you proceed you will likely fall into a pit.
-
-> x
-
-It is now pitch dark.  If you proceed you will likely fall into a pit.
-
-> i
-
-You are currently holding the following:
-Black rod
-Small bottle
-
-> news
-
-Open Adventure is an author-approved open-source release of
-Version 2.5 with, as yet, no gameplay changes.
-Version 2.5 was essentially the same as Version II; the cave and the
-hazards therein are unchanged, and top score is still 430 points.
-There are a few more hints, especially for some of the more obscure
-puzzles.  There are a few minor bugfixes and cosmetic changes.  You
-can now save a game and resume it at once (formerly you had to wait a
-while first), but it now costs you a few points each time you save the
-game.  Saved games are now stored in much smaller files than before.
-
-> go back
-
->>Foof!<<
-
-You're inside building.
-
-There are some keys on the ground here.
-
-There is a lamp shining nearby.
-
-> fuck
-
-Watch it!
-
-> walk
-
-Where?
-
-> fly
-
-Though you flap your arms furiously, it is to no avail.
-
-> say boo
-
-Okay, "boo".
-
-> score
-
-You have garnered 27 out of a possible 430 points, using 118 turns.
-
-> z
-
-OK
-
-> score
-
-You have garnered 27 out of a possible 430 points, using 120 turns.
-
-> quit keys
-
-Huh?
-
-> out
-
-You're in front of building.
-
-> s
-
-You're in valley.
-
-> s
-
-At your feet all the water of the stream splashes into a 2-inch slit
-in the rock.  Downstream the streambed is bare rock.
-
-> down
-
-You don't fit through a two-inch slit!
-
-You're at slit in streambed.
-
-> s
-
-You are in a 20-foot depression floored with bare dirt.  Set into the
-dirt is a strong steel grate mounted in concrete.  A dry streambed
-leads into the depression.
-
-The grate is locked.
-
-> in
-
-You can't go through a locked steel grate!
-
-You're outside grate.
-
-The grate is locked.
-
-> seed -123
-
-Seed set to -123
-
-You're outside grate.
-
-The grate is locked.
-
-> no
-
-OK
-
-Are you trying to get into the cave?
-
-> quit
-
-Please answer the question.
-
-Are you trying to get into the cave?
-
-> yes
-
-I am prepared to give you a hint, but it will cost you 2 points.
+> 
+You scored 27 out of a possible 430, using 17 turns.
 
-Do you want the hint?
+You are obviously a rank amateur.  Better luck next time.
 
+To achieve the next higher rating, you need 19 more points.
diff --git a/tests/illformed.log b/tests/illformed.log
index 59315fe..0cb22e0 100644
--- a/tests/illformed.log
+++ b/tests/illformed.log
@@ -1,4 +1,7 @@
 ## Test for various cases not found in walkthroughs.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE This is busted under advent430 -- see comments within.
 foo
 
 y
@@ -13,130 +16,16 @@ say rub
 say grate
 _
 back
-seed
+# advent430 doesn't have this command
 waste
+# seed should cause a compint when argumentless,
+seed
 eat grate
 23
 eat building
 in
 # Z'ZZZ Word correct, but does nothing
 say F'UNJ
-# Say bigwords when giant isn't around
-say fee
-say fie
-say foe
-say fum
+# Meant to evoke "I don't know in from out here."
 in
 keys
-throw food
-nothing food
-calm food
-walk food
-score food
-foo food
-brief food
-blast food
-find grate
-light food
-lock food
-unlock food
-extinguish food
-suspend food
-resume food
-crawl
-out
-stream
-lock
-take water
-blast
-building
-cave
-enter stream
-try three words
-listen
-carry
-forward
-eat
-drink
-throw keys
-find keys
-inven keys
-nothing
-in
-listen
-find keys
-unlock keys
-find foo
-find bar
-carry
-blast
-take bottle
-find bottle
-drink water
-fill bottle
-throw axe
-throw knife
-lock
-unlock
-throw
-attack
-unlock chain
-fill urn
-eat keys
-discard keys
-drink keys
-off keys
-break keys
-wake keys
-take keys
-feed keys
-fly keys
-pour keys
-throw keys
-foo up
-get
-food
-eat food
-drink blood
-drink keys
-light keys
-brief
-frob grate
-read grate
-grate
-pour bottle
-fill bottle
-building
-on
-pour bottle
-xyzzy
-take rod
-wave rod
-listen
-quit
-n
-read
-look
-l
-x
-i
-news
-go back
-fuck
-walk
-fly
-say boo
-score
-z
-score
-quit keys
-out
-s
-s
-down
-s
-in
-seed -123
-no
-quit
-yes
diff --git a/tests/illformed2.chk b/tests/illformed2.chk
new file mode 100644
index 0000000..ab2095b
--- /dev/null
+++ b/tests/illformed2.chk
@@ -0,0 +1,553 @@
+
+Welcome to Adventure!!  Would you like instructions?
+
+> n
+
+You are standing at the end of a road before a small brick building.
+Around you is a forest.  A small stream flows out of the building and
+down a gully.
+
+> seed 1635997320
+
+Seed set to 1635997320
+
+You're in front of building.
+
+> back
+
+You can't get there from here.
+
+You're in front of building.
+
+> say axe
+
+Okay, "axe".
+
+> say rub
+
+Okay, "rub".
+
+> say grate
+
+Okay, "grate".
+
+> _
+
+Sorry, I don't know the word "_".
+
+> back
+
+Sorry, but I no longer seem to remember how it was you got here.
+
+You're in front of building.
+
+> 23
+
+Sorry, I don't know the word "23".
+
+> say F'UNJ
+
+Nothing happens.
+
+> in
+
+You are inside a building, a well house for a large spring.
+
+There are some keys on the ground here.
+
+There is a shiny brass lamp nearby.
+
+There is food here.
+
+There is a bottle of water here.
+
+> keys
+
+What do you want to do with the keys?
+
+> throw food
+
+You aren't carrying it!
+
+> nothing food
+
+OK
+
+> calm food
+
+I'm game.  Would you care to explain how?
+
+> walk food
+
+Where?
+
+> score food
+
+Huh?
+
+> foo food
+
+I don't know how.
+
+> brief food
+
+On what?
+
+> blast food
+
+Blasting requires dynamite.
+
+> find grate
+
+I can only tell you what you see as you move about and manipulate
+things.  I cannot tell you where remote things are.
+
+> light food
+
+I'm afraid I don't understand.
+
+> lock food
+
+I don't know how to lock or unlock such a thing.
+
+> unlock food
+
+I don't know how to lock or unlock such a thing.
+
+> extinguish food
+
+I'm afraid I don't understand.
+
+> suspend food
+
+Huh?
+
+> resume food
+
+Huh?
+
+> crawl
+
+Which way?
+
+You're inside building.
+
+There are some keys on the ground here.
+
+There is a shiny brass lamp nearby.
+
+There is food here.
+
+There is a bottle of water here.
+
+> out
+
+You're in front of building.
+
+> stream
+
+You are in a valley in the forest beside a stream tumbling along a
+rocky bed.
+
+> lock
+
+There is nothing here with a lock!
+
+> take water
+
+You have nothing in which to carry it.
+
+> blast
+
+Blasting requires dynamite.
+
+> building
+
+You are standing at the end of a road before a small brick building.
+Around you is a forest.  A small stream flows out of the building and
+down a gully.
+
+> cave
+
+I don't know where the cave is, but hereabouts no stream can run on
+the surface for long.  I would try the stream.
+
+You're in front of building.
+
+> enter stream
+
+Your feet are now wet.
+
+> try three words
+
+Please stick to 1- and 2-word commands.
+
+> listen
+
+The stream is gurgling placidly.
+
+> carry
+
+Carry what?
+
+> forward
+
+I am unsure how you are facing.  Use compass points or nearby objects.
+
+You're in front of building.
+
+> eat
+
+Eat what?
+
+> drink
+
+You have taken a drink from the stream.  The water tastes strongly of
+minerals, but is not unpleasant.  It is extremely cold.
+
+> throw keys
+
+I see no keys here.
+
+> find keys
+
+I can only tell you what you see as you move about and manipulate
+things.  I cannot tell you where remote things are.
+
+> inven keys
+
+I can only tell you what you see as you move about and manipulate
+things.  I cannot tell you where remote things are.
+
+> nothing
+
+OK
+
+> in
+
+You're inside building.
+
+There are some keys on the ground here.
+
+There is a shiny brass lamp nearby.
+
+There is food here.
+
+There is a bottle of water here.
+
+> listen
+
+The stream is gurgling placidly.
+
+> find keys
+
+I believe what you want is right here with you.
+
+> unlock keys
+
+You can't unlock the keys.
+
+> find bar
+
+Sorry, I don't know the word "bar".
+
+> carry
+
+Carry what?
+
+> blast
+
+Blasting requires dynamite.
+
+> take bottle
+
+OK
+
+> find bottle
+
+You are already carrying it!
+
+> drink water
+
+The bottle of water is now empty.
+
+> fill bottle
+
+Your bottle is now full of water.
+
+> throw axe
+
+I see no axe here.
+
+> throw knife
+
+I see no knife here.
+
+> lock
+
+There is nothing here with a lock!
+
+> unlock
+
+There is nothing here with a lock!
+
+> throw
+
+Throw what?
+
+> attack
+
+There is nothing here to attack.
+
+> unlock chain
+
+I see no chain here.
+
+> fill urn
+
+I see no urn here.
+
+> eat keys
+
+Don't be ridiculous!
+
+> discard keys
+
+You aren't carrying it!
+
+> drink keys
+
+Don't be ridiculous!
+
+> off keys
+
+I'm afraid I don't understand.
+
+> break keys
+
+It is beyond your power to do that.
+
+> wake keys
+
+Don't be ridiculous!
+
+> take keys
+
+OK
+
+> feed keys
+
+I'm game.  Would you care to explain how?
+
+> fly keys
+
+I'm game.  Would you care to explain how?
+
+> pour keys
+
+You can't pour that.
+
+> throw keys
+
+OK
+
+> foo up
+
+There is no way to go that direction.
+
+You're inside building.
+
+There are some keys on the ground here.
+
+There is a shiny brass lamp nearby.
+
+There is food here.
+
+> get
+
+Get what?
+
+> food
+
+OK
+
+> eat food
+
+Thank you, it was delicious!
+
+> drink blood
+
+I see no blood here.
+
+> drink keys
+
+Don't be ridiculous!
+
+> light keys
+
+I'm afraid I don't understand.
+
+> brief
+
+Okay, from now on I'll only describe a place in full the first time
+you come to it.  To get the full description, say "look".
+
+> frob grate
+
+Sorry, I don't know the word "frob".
+
+> read grate
+
+I see no grate here.
+
+> pour bottle
+
+Your bottle is empty and the ground is wet.
+
+> fill bottle
+
+Your bottle is now full of water.
+
+> building
+
+I don't know how to apply that word here.
+
+You're inside building.
+
+There are some keys on the ground here.
+
+There is a shiny brass lamp nearby.
+
+> on
+
+Your lamp is now on.
+
+> pour bottle
+
+Your bottle is empty and the ground is wet.
+
+> xyzzy
+
+>>Foof!<<
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> take rod
+
+OK
+
+> wave rod
+
+Nothing happens.
+
+> listen
+
+All is silent.
+
+> quit
+
+Do you really want to quit now?
+
+> n
+
+OK
+
+> read
+
+Read what?
+
+> look
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> go back
+
+>>Foof!<<
+
+You're inside building.
+
+There are some keys on the ground here.
+
+There is a lamp shining nearby.
+
+> fuck
+
+Watch it!
+
+> walk
+
+Where?
+
+> fly
+
+Though you flap your arms furiously, it is to no avail.
+
+> say boo
+
+Okay, "boo".
+
+> score
+
+You have garnered 32 out of a possible 430 points, using 101 turns.
+
+> z
+
+OK
+
+> score
+
+You have garnered 32 out of a possible 430 points, using 103 turns.
+
+> quit keys
+
+Huh?
+
+> out
+
+You're in front of building.
+
+> s
+
+You're in valley.
+
+> s
+
+At your feet all the water of the stream splashes into a 2-inch slit
+in the rock.  Downstream the streambed is bare rock.
+
+> down
+
+You don't fit through a two-inch slit!
+
+You're at slit in streambed.
+
+> s
+
+You are in a 20-foot depression floored with bare dirt.  Set into the
+dirt is a strong steel grate mounted in concrete.  A dry streambed
+leads into the depression.
+
+The grate is locked.
+
+> in
+
+You can't go through a locked steel grate!
+
+You're outside grate.
+
+The grate is locked.
+
+> seed -123
+
+Seed set to -123
+
+You're outside grate.
+
+The grate is locked.
+
+> 
+You scored 32 out of a possible 430, using 110 turns.
+
+You are obviously a rank amateur.  Better luck next time.
+
+To achieve the next higher rating, you need 14 more points.
diff --git a/tests/illformed2.log b/tests/illformed2.log
new file mode 100644
index 0000000..f6193d7
--- /dev/null
+++ b/tests/illformed2.log
@@ -0,0 +1,138 @@
+## Test for various cases not found in walkthroughs (advent430-compatible).
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+# Commented-out lines cause troble in advent430
+n
+seed 1635997320
+back
+# Next three lines were buggy
+say axe
+say rub
+say grate
+_
+back
+#eat grate
+23
+#eat building
+#in
+# Z'ZZZ Word correct, but does nothing
+say F'UNJ
+# Say bigwords when giant isn't around
+#say fee
+#say fie
+#say foe
+#say fum
+# Meant to evoke "I don't know in from out here."
+in
+keys
+throw food
+nothing food
+calm food
+walk food
+score food
+foo food
+brief food
+blast food
+find grate
+light food
+lock food
+unlock food
+extinguish food
+suspend food
+resume food
+crawl
+out
+stream
+lock
+take water
+blast
+building
+cave
+enter stream
+try three words
+listen
+carry
+forward
+eat
+drink
+throw keys
+find keys
+inven keys
+nothing
+in
+listen
+find keys
+unlock keys
+find bar
+carry
+blast
+take bottle
+find bottle
+drink water
+fill bottle
+throw axe
+throw knife
+lock
+unlock
+throw
+attack
+unlock chain
+fill urn
+eat keys
+discard keys
+drink keys
+off keys
+break keys
+wake keys
+take keys
+feed keys
+fly keys
+pour keys
+throw keys
+foo up
+get
+food
+eat food
+drink blood
+drink keys
+light keys
+brief
+frob grate
+read grate
+#grate
+pour bottle
+fill bottle
+building
+on
+pour bottle
+xyzzy
+take rod
+wave rod
+listen
+quit
+n
+read
+look
+#l
+#x
+#i
+#news
+go back
+fuck
+walk
+fly
+say boo
+score
+z
+score
+quit keys
+out
+s
+s
+down
+s
+in
+seed -123
+#no
+#quit
+#yes
diff --git a/tests/intransitivecarry.chk b/tests/intransitivecarry.chk
index 510a9bd..4fe9674 100644
--- a/tests/intransitivecarry.chk
+++ b/tests/intransitivecarry.chk
@@ -35,7 +35,7 @@ OK
 
 OK
 
-
+> 
 You scored 32 out of a possible 430, using 5 turns.
 
 You are obviously a rank amateur.  Better luck next time.
diff --git a/tests/intransitivecarry.log b/tests/intransitivecarry.log
index 640a296..acef62e 100644
--- a/tests/intransitivecarry.log
+++ b/tests/intransitivecarry.log
@@ -1,4 +1,6 @@
 ## Carry when only one object is present
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 in
 carry lamp
diff --git a/tests/isofoo.log b/tests/isofoo.log
deleted file mode 100644
index 82b5906..0000000
--- a/tests/isofoo.log
+++ /dev/null
@@ -1,3 +0,0 @@
-## Test isolated 'foo' word
-n
-foo
diff --git a/tests/issue36.chk b/tests/issue36.chk
index 412f019..99d82df 100644
--- a/tests/issue36.chk
+++ b/tests/issue36.chk
@@ -33,7 +33,7 @@ Get what?
 
 OK
 
-
+> 
 You scored 32 out of a possible 430, using 3 turns.
 
 You are obviously a rank amateur.  Better luck next time.
diff --git a/tests/issue36.log b/tests/issue36.log
index cab1d04..fa8ef7f 100644
--- a/tests/issue36.log
+++ b/tests/issue36.log
@@ -1,4 +1,6 @@
 ## Test handling of object after transitive verb.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 826186526
 in
diff --git a/tests/issue37.chk b/tests/issue37.chk
index 6d8772b..4aa9320 100644
--- a/tests/issue37.chk
+++ b/tests/issue37.chk
@@ -32,7 +32,7 @@ OK
 You are currently holding the following:
 Tasty food
 
-
+> 
 You scored 32 out of a possible 430, using 4 turns.
 
 You are obviously a rank amateur.  Better luck next time.
diff --git a/tests/issue37.log b/tests/issue37.log
index ded6a10..14afe5e 100644
--- a/tests/issue37.log
+++ b/tests/issue37.log
@@ -1,4 +1,6 @@
 ## Test handling of transitive verb after noun
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 in
 food
diff --git a/tests/lampdim.chk b/tests/lampdim.chk
index 2ea31c6..cfbb010 100644
--- a/tests/lampdim.chk
+++ b/tests/lampdim.chk
@@ -2508,7 +2508,7 @@ There is a message scrawled in the dust in a flowery script, reading:
 There is a massive vending machine here, swung back to reveal a
 southward passage.
 
-
+> 
 You scored 343 out of a possible 430, using 406 turns.
 
 Your score puts you in Master Adventurer Class C.
diff --git a/tests/lampdim.log b/tests/lampdim.log
index fe4fc4e..514b6a2 100644
--- a/tests/lampdim.log
+++ b/tests/lampdim.log
@@ -1,4 +1,6 @@
 ## Test the case where your lamp goes dim
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
diff --git a/tests/lampdim2.chk b/tests/lampdim2.chk
index bd6215a..740e719 100644
--- a/tests/lampdim2.chk
+++ b/tests/lampdim2.chk
@@ -2595,7 +2595,7 @@ It is now pitch dark.  If you proceed you will likely fall into a pit.
 
 Your lamp has run out of power.
 
-
+> 
 You scored 368 out of a possible 430, using 423 turns.
 
 Your score puts you in Master Adventurer Class C.
diff --git a/tests/lampdim2.log b/tests/lampdim2.log
index 7004519..3afe71c 100644
--- a/tests/lampdim2.log
+++ b/tests/lampdim2.log
@@ -1,4 +1,6 @@
 ## Try (and fail) to carry message at vending machine
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
@@ -426,4 +428,4 @@ n
 s
 n
 s
-lamp on
\ No newline at end of file
+lamp on
diff --git a/tests/lampdim3.log b/tests/lampdim3.log
index cb8ba7a..e944d4e 100644
--- a/tests/lampdim3.log
+++ b/tests/lampdim3.log
@@ -1,4 +1,6 @@
 ## Die while closing
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
@@ -432,4 +434,4 @@ n
 s
 n
 up
-down
\ No newline at end of file
+down
diff --git a/tests/listen.log b/tests/listen.log
index 135fdbc..6aa7b97 100644
--- a/tests/listen.log
+++ b/tests/listen.log
@@ -1,4 +1,6 @@
 ## Check that listen command hears all objects as well as location sound
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 no
 seed 1181530211
 e
diff --git a/tests/listenloud.log b/tests/listenloud.log
index 3e820e4..f0c62fe 100644
--- a/tests/listenloud.log
+++ b/tests/listenloud.log
@@ -1,4 +1,6 @@
 ## Attempt to listen at a loud location
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56
 n
 seed 1495951709
@@ -139,4 +141,4 @@ u
 reservoir
 Q'IBJ
 n
-listen
\ No newline at end of file
+listen
diff --git a/tests/lockchain.chk b/tests/lockchain.chk
index 791991f..5645019 100644
--- a/tests/lockchain.chk
+++ b/tests/lockchain.chk
@@ -1888,3 +1888,12 @@ Oh dear, you seem to have gotten yourself killed.  I might be able to
 help you out, but I've never really done this before.  Do you want me
 to try to reincarnate you?
 
+> n
+
+OK
+
+You scored 219 out of a possible 430, using 328 turns.
+
+You may now consider yourself a "Seasoned Adventurer".
+
+To achieve the next higher rating, you need 32 more points.
diff --git a/tests/lockchain.log b/tests/lockchain.log
index a9db9e6..f311485 100644
--- a/tests/lockchain.log
+++ b/tests/lockchain.log
@@ -1,4 +1,6 @@
 ## Test multiple re-locking and unlocking of bear's chain
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56
 n
 seed 1635997320
@@ -334,3 +336,4 @@ s
 listen
 n
 jump
+n
diff --git a/tests/logopt.chk b/tests/logopt.chk
index 4defeae..e48c318 100644
--- a/tests/logopt.chk
+++ b/tests/logopt.chk
@@ -21,7 +21,7 @@ There is a bottle of water here.
 
 > 
 
-
+> 
 You scored 32 out of a possible 430, using 1 turn.
 
 You are obviously a rank amateur.  Better luck next time.
diff --git a/tests/logopt.log b/tests/logopt.log
index 5074144..ee4a860 100644
--- a/tests/logopt.log
+++ b/tests/logopt.log
@@ -1,4 +1,6 @@
 ## Exercise logging option and seed dump
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 #options: -l scratch.tmp
 n
 in
diff --git a/tests/foofum.chk b/tests/magicwords.chk
similarity index 98%
rename from tests/foofum.chk
rename to tests/magicwords.chk
index 6424ad7..4db287a 100644
--- a/tests/foofum.chk
+++ b/tests/magicwords.chk
@@ -13,6 +13,14 @@ Seed set to 1838473132
 
 You're in front of building.
 
+> foo
+
+Nothing happens.
+
+> say foo
+
+Nothing happens.
+
 > in
 
 You are inside a building, a well house for a large spring.
@@ -25,6 +33,54 @@ There is food here.
 
 There is a bottle of water here.
 
+> say fee
+
+OK
+
+> say fie
+
+OK
+
+> say foe
+
+OK
+
+> say foo
+
+Nothing happens.
+
+> z
+
+OK
+
+> say fee
+
+OK
+
+> say fie
+
+OK
+
+> say foe
+
+OK
+
+> say fum
+
+Well, that was remarkably pointless!
+
+> z
+
+OK
+
+> find foo
+
+Nothing happens.
+
+> z
+
+OK
+
 > take lamp
 
 OK
@@ -1822,15 +1878,8 @@ OK
 
 What's the matter, can't you read?  Now you'd best start over.
 
-> quit
-
-Do you really want to quit now?
-
-> yes
-
-OK
-
-You scored 253 out of a possible 430, using 304 turns.
+> 
+You scored 253 out of a possible 430, using 317 turns.
 
 You have reached "Junior Master" status.
 
diff --git a/tests/magicwords.log b/tests/magicwords.log
new file mode 100644
index 0000000..5e7f39a
--- /dev/null
+++ b/tests/magicwords.log
@@ -0,0 +1,359 @@
+## Test processing of various fee fie foe foo fum cases.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# How they're supposed to work:
+#
+# 1. The word "fum", from the famous phrase, "fee fie foe fum" is treated
+# as a red herring for the player and is handled differently in the
+# logic of the game
+#
+# 2. Each word of the magic phrase and the word "fum" can be preceded by
+# the word "say", so "say fee", "say fie", etc. will work, as
+# well. For "say fum", 'Okay, "FUM"' should NOT be the response,
+# similar to what is seen when other non-magic words are uttered with
+# "say"
+#
+# 3. The sequence is triggered by the first word "fee" only. If any of
+# the other words of the phrase or "fum" are said before "fee",
+# "nothing happens"
+#
+# 4. The phrase "fee fie foe foo" must be entered as four separate
+# commands, in order, without interruption. A move, like "east" or a
+# non-move, like "look", are both considered interruptions
+#
+# 5.  Once the sequence has begun, if any of the words of the phrase,
+# including a second "fee", are said out of order, or "fum" is spoken at
+# all during the sequence, the player is admonished for not being able
+# to read. The assumption here is the player at some point in the time
+# had previously read the phrase, but then messes up the order and/or
+# thinks "fum" was a part of the phrase when they attempt to speak
+# it. The player then must say "fee" again to restart the sequence. And
+# to clarify, a second "fee" in the sequence triggers the admonishment,
+# it does not restart the sequence
+#
+n
+seed 1838473132
+# Test isolated 'foo' word
+foo
+say foo
+in
+# Say bigwords ending with foo when not in Giant's Room
+say fee
+say fie
+say foe
+say foo
+z
+# Say bigwords ending with fum when not in Giant's Room
+say fee
+say fie
+say foe
+say fum
+z
+find foo
+z
+take lamp
+xyzzy
+on
+take rod
+e
+take cage
+w
+w
+w
+drop rod
+take bird
+take rod
+w
+free bird
+wave rod
+take necklace
+drop rod
+take bird
+take rod
+d
+d
+free bird
+drop rod
+drop cage
+take cage
+take bird
+w
+take coins
+e
+s
+take jewelry
+n
+up
+s
+take gold
+n
+d
+n
+n
+plugh
+extinguish lamp
+drop coins
+drop jewelry
+drop necklace
+drop gold
+plugh
+on
+s
+take silver
+s
+sw
+take axe
+w
+kill dragon
+yes
+drink blood
+take rug
+e
+e
+up
+d
+n
+n
+off
+plugh
+inven
+drop rug
+drop silver
+out
+s
+w
+n
+take appendage
+free bird
+drop cage
+listen
+s
+s
+n
+in
+take water
+plugh
+on
+plover
+ne
+take pyramid
+s
+plover
+s
+s
+take rod
+up
+w
+wave rod
+drop rod
+west
+take diamonds
+w
+w
+w
+s
+sw
+se
+s
+kill machine
+s
+s
+kill ogre
+n
+take ruby
+s
+w
+n
+n
+n
+nw
+d
+e
+e
+e
+e
+e
+throw axe
+take axe
+n
+n
+n
+off
+plugh
+drop ruby
+drop diamonds
+drop pyramid
+plugh
+on
+s
+s
+u
+n
+n
+d
+bedquilt
+throw axe
+take axe
+slab
+s
+d
+water plant
+u
+w
+u
+reservoir
+H'CFL
+n
+n
+nw
+u
+u
+u
+u
+ne
+take ebony
+sw
+d
+d
+d
+d
+d
+take water
+s
+s
+s
+s
+d
+s
+d
+water plant
+u
+drop appendage
+e
+d
+get oil
+
+u
+w
+d
+climb
+w
+n
+oil door
+drop bottle
+n
+take trident
+w
+d
+se
+n
+w
+drop trident
+drop ebony
+drop axe
+drop lantern
+e
+take emerald
+w
+take lamp
+take axe
+take ebony
+take trident
+nw
+s
+take vase
+se
+throw axe
+take axe
+e
+take pillow
+w
+drop axe
+ne
+e
+n
+open clam
+s
+u
+e
+u
+n
+off
+plugh
+drop pillow
+drop vase
+drop trident
+drop emerald
+drop ebony
+take keys
+take food
+plugh
+on
+s
+d
+w
+d
+n
+d
+d
+take pearl
+u
+u
+s
+w
+w
+w
+w
+d
+climb
+w
+get eggs
+n
+take bottle
+n
+w
+d
+sw
+u
+toss eggs
+ne
+ne
+barren
+in
+feed bear
+unlock chain
+take chain
+take bear
+fork
+ne
+e
+take spices
+drop keys
+fork
+w
+w
+sw
+free bear
+inven
+sw
+sw
+d
+se
+se
+w
+d
+get oil
+up
+e
+take axe
+w
+w
+d
+climb
+w
+# Now that we're at the Giant's Room, actual testing can start
+fee
+fie
+foe
+fum
diff --git a/tests/mazealldiff.chk b/tests/mazealldiff.chk
index 87aeb0d..00168a4 100644
--- a/tests/mazealldiff.chk
+++ b/tests/mazealldiff.chk
@@ -2509,7 +2509,7 @@ You are in a maze of little twisty passages, all different.
 
 You are in a twisting little maze of passages, all different.
 
-
+> 
 You scored 343 out of a possible 430, using 409 turns.
 
 Your score puts you in Master Adventurer Class C.
diff --git a/tests/mazealldiff.log b/tests/mazealldiff.log
index d129c13..2da3152 100644
--- a/tests/mazealldiff.log
+++ b/tests/mazealldiff.log
@@ -1,4 +1,6 @@
 ## Coverage of all LOC_DIFFERENT*
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
diff --git a/tests/mazehint.chk b/tests/mazehint.chk
index 0d00119..5c72b61 100644
--- a/tests/mazehint.chk
+++ b/tests/mazehint.chk
@@ -618,7 +618,7 @@ Do you want the hint?
 
 You can make the passages look less alike by dropping things.
 
-
+> 
 You scored 71 out of a possible 430, using 113 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/mazehint.log b/tests/mazehint.log
index 454b4f9..83ae210 100644
--- a/tests/mazehint.log
+++ b/tests/mazehint.log
@@ -1,4 +1,6 @@
 ## Elicit the maze hint.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1071883378
 in
diff --git a/tests/multifile.chk b/tests/multifile.chk
index 910fee2..991ea9c 100644
--- a/tests/multifile.chk
+++ b/tests/multifile.chk
@@ -1,7 +1,9 @@
 
 Welcome to Adventure!!  Would you like instructions?
 
-> ## Test isolated 'foo' word
+> ## Test handling of object after transitive verb.
+> # SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+> # SPDX-License-Identifier: BSD-2-Clause
 > n
 > n
 
@@ -9,18 +11,44 @@ You are standing at the end of a road before a small brick building.
 Around you is a forest.  A small stream flows out of the building and
 down a gully.
 
-> foo
-> foo
+> seed 826186526
+> seed 826186526
 
-Nothing happens.
+Seed set to 826186526
+
+You're in front of building.
+
+> in
+> in
+
+You are inside a building, a well house for a large spring.
+
+There are some keys on the ground here.
+
+There is a shiny brass lamp nearby.
+
+There is food here.
+
+There is a bottle of water here.
+
+> get
+> get
+
+Get what?
+
+> food
+> food
+
+OK
 
 > inven
 > inven
 
-You're not carrying anything.
+You are currently holding the following:
+Tasty food
 
 
-You scored 32 out of a possible 430, using 2 turns.
+You scored 32 out of a possible 430, using 4 turns.
 
 You are obviously a rank amateur.  Better luck next time.
 
diff --git a/tests/newfilter b/tests/newfilter
new file mode 100755
index 0000000..c5bad71
--- /dev/null
+++ b/tests/newfilter
@@ -0,0 +1,11 @@
+#!/bin/sh
+#
+# Filter the output from Open Adventure versions to make it compatible with
+# the filtered versions of logs made from advent430.
+sed \
+    -e '/bridge now spans the fissure/s//bridge spans the fissure/' \
+    -e '/ground/s//surface/' \
+    -e '/floor/s//surface/' \
+    -e "/Well, that was remarkably pointless!/s//What's the matter, can't you read?  Now you'd best start over./" \
+
+# end
diff --git a/tests/notrident.chk b/tests/notrident.chk
index 8e08825..88a8d6d 100644
--- a/tests/notrident.chk
+++ b/tests/notrident.chk
@@ -1316,7 +1316,7 @@ You're at brink of small pit.
 
 > 
 
-
+> 
 You scored 179 out of a possible 430, using 224 turns.
 
 You may now consider yourself a "Seasoned Adventurer".
diff --git a/tests/notrident.log b/tests/notrident.log
index e51a325..8e649cb 100644
--- a/tests/notrident.log
+++ b/tests/notrident.log
@@ -1,4 +1,6 @@
 ## Try to open clam without trident and fail
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1635997320
 in
diff --git a/tests/ogre_no_dwarves.chk b/tests/ogre_no_dwarves.chk
index dff2bc5..37492fa 100644
--- a/tests/ogre_no_dwarves.chk
+++ b/tests/ogre_no_dwarves.chk
@@ -152,7 +152,7 @@ A formidable ogre bars the northern exit.
 The ogre, who despite his bulk is quite agile, easily dodges your
 attack.  He seems almost amused by your puny effort.
 
-
+> 
 You scored 59 out of a possible 430, using 23 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/ogre_no_dwarves.log b/tests/ogre_no_dwarves.log
index 1d5b269..3ba7102 100644
--- a/tests/ogre_no_dwarves.log
+++ b/tests/ogre_no_dwarves.log
@@ -1,4 +1,6 @@
 ## Try to attack ogre with no dwarves present (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 25508795
 in
@@ -23,4 +25,4 @@ s
 kill machine
 s
 s
-attack
\ No newline at end of file
+attack
diff --git a/tests/ogrehint.chk b/tests/ogrehint.chk
index dbb8d8f..9391193 100644
--- a/tests/ogrehint.chk
+++ b/tests/ogrehint.chk
@@ -720,7 +720,7 @@ Brass lantern
 Leporine appendage
 Platinum pyramid
 
-
+> 
 You scored 101 out of a possible 430, using 108 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/ogrehint.log b/tests/ogrehint.log
index 12a9d02..58a8abf 100644
--- a/tests/ogrehint.log
+++ b/tests/ogrehint.log
@@ -1,4 +1,6 @@
 ## Elicit the ogre hint.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 437547289
 seed 1071883378
diff --git a/tests/oilplant.chk b/tests/oilplant.chk
index 2f74824..167a3b7 100644
--- a/tests/oilplant.chk
+++ b/tests/oilplant.chk
@@ -1146,7 +1146,7 @@ The plant indignantly shakes the oil off its leaves and asks, "Water?"
 
 You can't be serious!
 
-
+> 
 You scored 185 out of a possible 430, using 187 turns.
 
 You may now consider yourself a "Seasoned Adventurer".
diff --git a/tests/oilplant.log b/tests/oilplant.log
index 35eab35..3174357 100644
--- a/tests/oilplant.log
+++ b/tests/oilplant.log
@@ -1,4 +1,6 @@
 ## Attempt to oil the beanstalk after watering it
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
diff --git a/tests/oldfilter b/tests/oldfilter
new file mode 100755
index 0000000..c834e5f
--- /dev/null
+++ b/tests/oldfilter
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Filter the output from advent430 to make it compatible with
+# newer ones
+sed \
+    -e '/ *$/s///' \
+    -e '/bridge now spans the fissure/s//bridge spans the fissure/' \
+    -e '/imbedded/s//embedded/' \
+    -e '/persian/s//Persian/' \
+    -e '/swiss/s//Swiss/' \
+    -e '/eying/s//eyeing/' \
+    -e '/threshhold/s//threshold/' \
+    -e '/AXE/s//axe/' \
+    -e '/BAR/s//bar/' \
+    -e '/BOO/s//boo/' \
+    -e '/DOING/s//doing/' \
+    -e '/EW/s//ew/' \
+    -e '/FROB/s//frob/' \
+    -e '/GRATE/s//grate/' \
+    -e '/NAGGING/s//nagging/' \
+    -e '/RUB/s//rub/' \
+    -e '/SOMETHING/s//something/' \
+    -e '/ground/s//surface/' \
+    -e '/floor/s//surface/' \
+
+
+#end
+    
diff --git a/tests/oldstyle.log b/tests/oldstyle.log
index a70456d..a259abd 100644
--- a/tests/oldstyle.log
+++ b/tests/oldstyle.log
@@ -1,5 +1,8 @@
 ## Simple quit
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 #options: -o
+#NOCOMPARE Comment not interpreted by advent430
 n
 i
 l
diff --git a/tests/outcheck.sh b/tests/outcheck.sh
new file mode 100755
index 0000000..4dc5b0d
--- /dev/null
+++ b/tests/outcheck.sh
@@ -0,0 +1,7 @@
+#! /bin/sh
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+case $? in
+    0) echo "ok - $1 succeeded";;
+    *) echo "not ok - $1 failed";;
+esac
diff --git a/tests/oysterbug.chk b/tests/oysterbug.chk
new file mode 100644
index 0000000..871b185
--- /dev/null
+++ b/tests/oysterbug.chk
@@ -0,0 +1,2930 @@
+
+Welcome to Adventure!!  Would you like instructions?
+
+> n
+
+You are standing at the end of a road before a small brick building.
+Around you is a forest.  A small stream flows out of the building and
+down a gully.
+
+> seed 1838473132
+
+Seed set to 1838473132
+
+You're in front of building.
+
+> in
+
+You are inside a building, a well house for a large spring.
+
+There are some keys on the ground here.
+
+There is a shiny brass lamp nearby.
+
+There is food here.
+
+There is a bottle of water here.
+
+> take lamp
+
+OK
+
+> xyzzy
+
+>>Foof!<<
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> on
+
+Your lamp is now on.
+
+You are in a debris room filled with stuff washed in from the surface.
+A low wide passage with cobbles becomes plugged with mud and debris
+here, but an awkward canyon leads upward and west.  In the mud someone
+has scrawled, "MAGIC WORD XYZZY".
+
+A three foot black rod with a rusty star on an end lies nearby.
+
+> take rod
+
+OK
+
+> e
+
+You are crawling over cobbles in a low passage.  There is a dim light
+at the east end of the passage.
+
+There is a small wicker cage discarded nearby.
+
+> take cage
+
+OK
+
+> w
+
+You're in debris room.
+
+> w
+
+You are in an awkward sloping east/west canyon.
+
+> w
+
+You are in a splendid chamber thirty feet high.  The walls are frozen
+rivers of orange stone.  An awkward canyon and a good passage exit
+from east and west sides of the chamber.
+
+A cheerful little bird is sitting here singing.
+
+> drop rod
+
+OK
+
+> take bird
+
+OK
+
+> take rod
+
+OK
+
+> w
+
+At your feet is a small pit breathing traces of white mist.  An east
+passage ends here except for a small crack leading on.
+
+Rough stone steps lead down the pit.
+
+> free bird
+
+OK
+
+> wave rod
+
+The bird flies about agitatedly for a moment, then disappears through
+the crack.  It reappears shortly, carrying in its beak a jade
+necklace, which it drops at your feet.
+
+> take necklace
+
+OK
+
+> drop rod
+
+OK
+
+> take bird
+
+OK
+
+> take rod
+
+OK
+
+> d
+
+You are at one end of a vast hall stretching forward out of sight to
+the west.  There are openings to either side.  Nearby, a wide stone
+staircase leads downward.  The hall is filled with wisps of white mist
+swaying to and fro almost as if alive.  A cold wind blows up the
+staircase.  There is a passage at the top of a dome behind you.
+
+Rough stone steps lead up the dome.
+
+> d
+
+You are in the Hall of the Mountain King, with passages off in all
+directions.
+
+A huge green fierce snake bars the way!
+
+> free bird
+
+The little bird attacks the green snake, and in an astounding flurry
+drives the snake away.
+
+> drop rod
+
+OK
+
+> drop cage
+
+OK
+
+> take cage
+
+OK
+
+> take bird
+
+OK
+
+> w
+
+You are in the west side chamber of the Hall of the Mountain King.
+A passage continues west and up here.
+
+There are many coins here!
+
+> take coins
+
+OK
+
+> e
+
+You're in Hall of Mt King.
+
+A three foot black rod with a rusty star on an end lies nearby.
+
+> s
+
+You are in the south side chamber.
+
+There is precious jewelry here!
+
+> take jewelry
+
+OK
+
+> n
+
+You're in Hall of Mt King.
+
+A three foot black rod with a rusty star on an end lies nearby.
+
+> up
+
+You're in Hall of Mists.
+
+Rough stone steps lead up the dome.
+
+> s
+
+This is a low room with a crude note on the wall.  The note says,
+"You won't get it up the steps".
+
+There is a large sparkling nugget of gold here!
+
+> take gold
+
+OK
+
+> n
+
+You're in Hall of Mists.
+
+> d
+
+You're in Hall of Mt King.
+
+A three foot black rod with a rusty star on an end lies nearby.
+
+> n
+
+You are in a low n/s passage at a hole in the floor.  The hole goes
+down to an e/w passage.
+
+There are bars of silver here!
+
+> n
+
+You are in a large room, with a passage to the south, a passage to the
+west, and a wall of broken rock to the east.  There is a large "Y2" on
+a rock in the room's center.
+
+A hollow voice says "PLUGH".
+
+> plugh
+
+>>Foof!<<
+
+You're inside building.
+
+There are some keys on the ground here.
+
+There is food here.
+
+There is a bottle of water here.
+
+> extinguish lamp
+
+Your lamp is now off.
+
+> drop coins
+
+OK
+
+> drop jewelry
+
+OK
+
+> drop necklace
+
+OK
+
+> drop gold
+
+OK
+
+> plugh
+
+>>Foof!<<
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> on
+
+Your lamp is now on.
+
+You're at "Y2".
+
+> s
+
+You're in n/s passage above e/w passage.
+
+There are bars of silver here!
+
+> take silver
+
+OK
+
+> s
+
+You're in Hall of Mt King.
+
+A three foot black rod with a rusty star on an end lies nearby.
+
+> sw
+
+A little dwarf just walked around a corner, saw you, threw a little
+axe at you which missed, cursed, and ran away.
+
+You are in a secret canyon which here runs e/w.  It crosses over a
+very tight canyon 15 feet below.  If you go down you may not be able
+to get back up.
+
+There is a little axe here.
+
+> take axe
+
+OK
+
+> w
+
+You are in a secret canyon which exits to the north and east.
+
+A huge green fierce dragon bars the way!
+
+The dragon is sprawled out on a Persian rug!!
+
+> kill dragon
+
+With what?  Your bare hands?
+
+> yes
+
+Congratulations!  You have just vanquished a dragon with your bare
+hands!  (Unbelievable, isn't it?)
+
+You are in a secret canyon which exits to the north and east.
+
+There is a Persian rug spread out on the floor!
+
+The blood-specked body of a huge green dead dragon lies to one side.
+
+> drink blood
+
+Your head buzzes strangely for a moment.
+
+> take rug
+
+OK
+
+> e
+
+You're in secret e/w canyon above tight canyon.
+
+> e
+
+You are in the Hall of the Mountain King, with passages off in all
+directions.
+
+A three foot black rod with a rusty star on an end lies nearby.
+
+> up
+
+There is a threatening little dwarf in the room with you!
+
+One sharp nasty knife is thrown at you!
+
+It misses!
+
+You're in Hall of Mists.
+
+Rough stone steps lead up the dome.
+
+> d
+
+There is a threatening little dwarf in the room with you!
+
+You're in Hall of Mt King.
+
+A three foot black rod with a rusty star on an end lies nearby.
+
+> n
+
+There is a threatening little dwarf in the room with you!
+
+You're in n/s passage above e/w passage.
+
+> n
+
+There is a threatening little dwarf in the room with you!
+
+You're at "Y2".
+
+A hollow voice says "PLUGH".
+
+> off
+
+Your lamp is now off.
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> plugh
+
+>>Foof!<<
+
+You're inside building.
+
+There is a large sparkling nugget of gold here!
+
+A precious jade necklace has been dropped here!
+
+There is precious jewelry here!
+
+There are many coins here!
+
+There are some keys on the ground here.
+
+There is food here.
+
+There is a bottle of water here.
+
+> inven
+
+You are currently holding the following:
+Brass lantern
+Wicker cage
+Little bird in cage
+Dwarf's axe
+Bars of silver
+Persian rug
+
+> drop rug
+
+OK
+
+> drop silver
+
+OK
+
+> out
+
+You're in front of building.
+
+> s
+
+You are in a valley in the forest beside a stream tumbling along a
+rocky bed.
+
+> w
+
+You are wandering aimlessly through the forest.
+
+> n
+
+You are wandering aimlessly through the forest.
+
+Your keen eye spots a severed leporine appendage lying on the ground.
+
+> take appendage
+
+OK
+
+> free bird
+
+OK
+
+> drop cage
+
+OK
+
+> listen
+
+The bird is singing to you in gratitude for your having returned it to
+its home.  In return, it informs you of a magic word which it thinks
+you may find useful somewhere near the Hall of Mists.  The magic word
+changes frequently, but for now the bird believes it is "H'CFL".  You
+thank the bird for this information, and it flies off into the forest.
+
+> s
+
+You are wandering aimlessly through the forest.
+
+> s
+
+You're in valley.
+
+> n
+
+You're in front of building.
+
+> in
+
+You're inside building.
+
+There are bars of silver here!
+
+There is a Persian rug spread out on the floor!
+
+There is a large sparkling nugget of gold here!
+
+A precious jade necklace has been dropped here!
+
+There is precious jewelry here!
+
+There are many coins here!
+
+There are some keys on the ground here.
+
+There is food here.
+
+There is a bottle of water here.
+
+> take water
+
+OK
+
+> plugh
+
+>>Foof!<<
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> on
+
+Your lamp is now on.
+
+You're at "Y2".
+
+> plover
+
+>>Foof!<<
+
+You're in a small chamber lit by an eerie green light.  An extremely
+narrow tunnel exits to the west.  A dark corridor leads ne.
+
+There is an emerald here the size of a plover's egg!
+
+> ne
+
+You're in the dark-room.  A corridor leading south is the only exit.
+
+A massive stone tablet embedded in the wall reads:
+"Congratulations on bringing light into the dark-room!"
+
+There is a platinum pyramid here, 8 inches on a side!
+
+> take pyramid
+
+OK
+
+> s
+
+You're in Plover Room.
+
+There is an emerald here the size of a plover's egg!
+
+> plover
+
+>>Foof!<<
+
+You're at "Y2".
+
+A hollow voice says "PLUGH".
+
+> s
+
+You're in n/s passage above e/w passage.
+
+> s
+
+You're in Hall of Mt King.
+
+A three foot black rod with a rusty star on an end lies nearby.
+
+> take rod
+
+OK
+
+> up
+
+You're in Hall of Mists.
+
+Rough stone steps lead up the dome.
+
+> w
+
+You are on the east bank of a fissure slicing clear across the hall.
+The mist is quite thick here, and the fissure is too wide to jump.
+
+> wave rod
+
+A crystal bridge now spans the fissure.
+
+> drop rod
+
+OK
+
+> west
+
+You are on the west side of the fissure in the Hall of Mists.
+
+There are diamonds here!
+
+A crystal bridge spans the fissure.
+
+> take diamonds
+
+OK
+
+> w
+
+There is a threatening little dwarf in the room with you!
+
+One sharp nasty knife is thrown at you!
+
+It misses!
+
+You are at the west end of the Hall of Mists.  A low wide crawl
+continues west and another goes north.  To the south is a little
+passage 6 feet off the floor.
+
+> w
+
+There is a threatening little dwarf in the room with you!
+
+You are at the east end of a very long hall apparently without side
+chambers.  To the east a low wide crawl slants up.  To the north a
+round two foot hole slants down.
+
+> w
+
+There is a threatening little dwarf in the room with you!
+
+You are at the west end of a very long featureless hall.  The hall
+joins up with a narrow north/south passage.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+You are in a maze of twisty little passages, all different.
+
+> sw
+
+There is a threatening little dwarf in the room with you!
+
+You are in a little maze of twisty passages, all different.
+
+> se
+
+There is a threatening little dwarf in the room with you!
+
+You are in a little maze of twisting passages, all different.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+Dead end
+
+There is a massive and somewhat battered vending machine here.  The
+instructions on it read: "Drop coins here to receive fresh batteries."
+
+> kill machine
+
+As you strike the vending machine, it pivots backward along with a
+section of wall, revealing a dark passage leading south.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+You are in a long, rough-hewn, north/south corridor.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+You are in a large chamber with passages to the west and north.
+
+A formidable ogre bars the northern exit.
+
+> kill ogre
+
+The ogre, who despite his bulk is quite agile, easily dodges your
+attack.  He seems almost amused by your puny effort.
+
+One sharp nasty knife is thrown at you!
+
+The ogre, distracted by your rush, is struck by the knife.  With a
+blood-curdling yell he turns and bounds after the dwarf, who flees
+in panic.  You are left alone in the room.
+
+> n
+
+You are in the ogre's storeroom.  The only exit is to the south.
+
+There is an enormous ruby here!
+
+> take ruby
+
+OK
+
+> s
+
+You are in a large chamber with passages to the west and north.
+
+> w
+
+You are in a long, rough-hewn, north/south corridor.
+
+> n
+
+Dead end
+
+There is a massive vending machine here, swung back to reveal a
+southward passage.
+
+> n
+
+You are in a little maze of twisting passages, all different.
+
+> n
+
+You are in a little maze of twisty passages, all different.
+
+> nw
+
+You are in a maze of twisty little passages, all different.
+
+> d
+
+You're at west end of long hall.
+
+> e
+
+You're at east end of long hall.
+
+> e
+
+You're at west end of Hall of Mists.
+
+> e
+
+You're on west bank of fissure.
+
+A crystal bridge spans the fissure.
+
+> e
+
+You're on east bank of fissure.
+
+A three foot black rod with a rusty star on an end lies nearby.
+
+A crystal bridge spans the fissure.
+
+> e
+
+There is a threatening little dwarf in the room with you!
+
+One sharp nasty knife is thrown at you!
+
+It misses!
+
+You are at one end of a vast hall stretching forward out of sight to
+the west.  There are openings to either side.  Nearby, a wide stone
+staircase leads downward.  The hall is filled with wisps of white mist
+swaying to and fro almost as if alive.  A cold wind blows up the
+staircase.  There is a passage at the top of a dome behind you.
+
+Rough stone steps lead up the dome.
+
+> throw axe
+
+You killed a little dwarf.  The body vanishes in a cloud of greasy
+black smoke.
+
+You're in Hall of Mists.
+
+There is a little axe here.
+
+Rough stone steps lead up the dome.
+
+> take axe
+
+OK
+
+> n
+
+You're in Hall of Mt King.
+
+> n
+
+You're in n/s passage above e/w passage.
+
+> n
+
+You are in a large room, with a passage to the south, a passage to the
+west, and a wall of broken rock to the east.  There is a large "Y2" on
+a rock in the room's center.
+
+A hollow voice says "PLUGH".
+
+> off
+
+Your lamp is now off.
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> plugh
+
+>>Foof!<<
+
+You're inside building.
+
+There are bars of silver here!
+
+There is a Persian rug spread out on the floor!
+
+There is a large sparkling nugget of gold here!
+
+A precious jade necklace has been dropped here!
+
+There is precious jewelry here!
+
+There are many coins here!
+
+There are some keys on the ground here.
+
+There is food here.
+
+> drop ruby
+
+OK
+
+> drop diamonds
+
+OK
+
+> drop pyramid
+
+OK
+
+> plugh
+
+>>Foof!<<
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> on
+
+Your lamp is now on.
+
+You're at "Y2".
+
+A hollow voice says "PLUGH".
+
+> s
+
+You are in a low n/s passage at a hole in the floor.  The hole goes
+down to an e/w passage.
+
+> s
+
+You're in Hall of Mt King.
+
+> u
+
+You're in Hall of Mists.
+
+Rough stone steps lead up the dome.
+
+> n
+
+You are in the Hall of the Mountain King, with passages off in all
+directions.
+
+> n
+
+You're in n/s passage above e/w passage.
+
+> d
+
+You are in a dirty broken passage.  To the east is a crawl.  To the
+west is a large passage.  Above you is a hole to another passage.
+
+> bedquilt
+
+There is a threatening little dwarf in the room with you!
+
+You are in Bedquilt, a long east/west passage with holes everywhere.
+To explore at random select north, south, up, or down.
+
+> throw axe
+
+You killed a little dwarf.
+
+You're in Bedquilt.
+
+There is a little axe here.
+
+> take axe
+
+OK
+
+> slab
+
+You are in a large low circular chamber whose floor is an immense slab
+fallen from the ceiling (Slab Room).  East and west there once were
+large passages, but they are now filled with boulders.  Low small
+passages go north and south, and the south one quickly bends west
+around the boulders.
+
+> s
+
+You are at the west end of the Twopit Room.  There is a large hole in
+the wall above the pit at this end of the room.
+
+> d
+
+You are at the bottom of the western pit in the Twopit Room.  There is
+a large hole in the wall about 25 feet above you.
+
+There is a tiny little plant in the pit, murmuring "water, water, ..."
+
+> water plant
+
+The plant spurts into furious growth for a few seconds.
+
+You're in west pit.
+
+There is a 12-foot-tall beanstalk stretching up out of the pit,
+bellowing "WATER!! WATER!!"
+
+> u
+
+You're at west end of Twopit Room.
+
+The top of a 12-foot-tall beanstalk is poking out of the west pit.
+
+> w
+
+You're in Slab Room.
+
+> u
+
+You are in a secret n/s canyon above a large room.
+
+> reservoir
+
+You are at the edge of a large underground reservoir.  An opaque cloud
+of white mist fills the room and rises rapidly upward.  The lake is
+fed by a stream, which tumbles out of a hole in the wall about 10 feet
+overhead and splashes noisily into the water somewhere within the
+mist.  There is a passage going back toward the south.
+
+> H'CFL
+
+The waters have parted to form a narrow path across the reservoir.
+
+> n
+
+You are walking across the bottom of the reservoir.  Walls of water
+rear up on either side.  The roar of the water cascading past is
+nearly deafening, and the mist is so thick you can barely see.
+
+> n
+
+You are at the northern edge of the reservoir.  A northwest passage
+leads sharply up from here.
+
+The waters have parted to form a narrow path across the reservoir.
+
+> nw
+
+You are scrambling along a treacherously steep, rocky passage.
+
+> u
+
+You are on a very steep incline, which widens at it goes upward.
+
+> u
+
+You are at the base of a nearly vertical cliff.  There are some
+slim footholds which would enable you to climb up, but it looks
+extremely dangerous.  Here at the base of the cliff lie the remains
+of several earlier adventurers who apparently failed to make it.
+
+> u
+
+You are climbing along a nearly vertical cliff.
+
+> u
+
+Just as you reach the top, your foot slips on a loose rock and you
+make one last desperate grab.  Your luck holds, as does your grip.
+With an enormous heave, you lift yourself to the ledge above.
+
+You are on a small ledge at the top of a nearly vertical cliff.
+There is a low crawl leading off to the northeast.
+
+> ne
+
+You have reached a dead end.
+
+There is a richly-carved ebony statuette here!
+
+> take ebony
+
+OK
+
+> sw
+
+You're at top of cliff.
+
+> d
+
+You are climbing along a nearly vertical cliff.
+
+> d
+
+You're at base of cliff.
+
+> d
+
+You are on a very steep incline, which widens at it goes upward.
+
+> d
+
+You are scrambling along a treacherously steep, rocky passage.
+
+> d
+
+You're north of reservoir.
+
+The waters have parted to form a narrow path across the reservoir.
+
+> take water
+
+Your bottle is now full of water.
+
+> s
+
+You're at bottom of reservoir.
+
+> s
+
+You're at reservoir.
+
+The waters have parted to form a narrow path across the reservoir.
+
+> s
+
+You are in a north/south canyon about 25 feet across.  The floor is
+covered by white mist seeping in from the north.  The walls extend
+upward for well over 100 feet.  Suspended from some unseen point far
+above you, an enormous two-sided mirror is hanging parallel to and
+midway between the canyon walls.  (The mirror is obviously provided
+for the use of the dwarves who, as you know, are extremely vain.)  A
+small window can be seen in either wall, some fifty feet up.
+
+> break mirror
+
+It is too far up for you to reach.
+
+> s
+
+You are in a secret n/s canyon above a large room.
+
+> d
+
+You're in Slab Room.
+
+> s
+
+You're at west end of Twopit Room.
+
+The top of a 12-foot-tall beanstalk is poking out of the west pit.
+
+> d
+
+You're in west pit.
+
+There is a 12-foot-tall beanstalk stretching up out of the pit,
+bellowing "WATER!! WATER!!"
+
+> water plant
+
+The plant grows explosively, almost filling the bottom of the pit.
+
+You're in west pit.
+
+There is a gigantic beanstalk stretching all the way up to the hole.
+
+> u
+
+You're at west end of Twopit Room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> drop appendage
+
+OK
+
+> e
+
+You are at the east end of the Twopit Room.  The floor here is
+littered with thin rock slabs, which make it easy to descend the pits.
+There is a path here bypassing the pits to connect passages from east
+and west.  There are holes all over, but the only big one is on the
+wall directly over the west pit where you can't get to it.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> d
+
+You are at the bottom of the eastern pit in the Twopit Room.  There is
+a small pool of oil in one corner of the pit.
+
+> get oil
+
+Your bottle is now full of oil.
+
+> 
+
+> u
+
+You're at east end of Twopit Room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> w
+
+You're at west end of Twopit Room.
+
+Your keen eye spots a severed leporine appendage lying on the ground.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> d
+
+You're in west pit.
+
+There is a gigantic beanstalk stretching all the way up to the hole.
+
+> climb
+
+You clamber up the plant and scurry through the hole at the top.
+
+You are in a long, narrow corridor stretching out of sight to the
+west.  At the eastern end is a hole through which you can see a
+profusion of leaves.
+
+> w
+
+You are in the Giant Room.  The ceiling here is too high up for your
+lamp to show it.  Cavernous passages lead east, north, and south.  On
+the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic].
+
+There is a large nest here, full of golden eggs!
+
+> n
+
+You are at one end of an immense north/south passage.
+
+The way north is barred by a massive, rusty, iron door.
+
+> unlock
+
+The door is extremely rusty and refuses to open.
+
+> oil door
+
+The oil has freed up the hinges so that the door will now move,
+although it requires some effort.
+
+> drop bottle
+
+OK
+
+> n
+
+You are in a magnificent cavern with a rushing stream, which cascades
+over a sparkling waterfall into a roaring whirlpool which disappears
+through a hole in the floor.  Passages exit to the south and west.
+
+There is a jewel-encrusted trident here!
+
+> take trident
+
+OK
+
+> w
+
+You are at the top of a steep incline above a large room.  You could
+climb down here, but you would not be able to climb up.  There is a
+passage leading back to the north.
+
+> d
+
+You are in a large low room.  Crawls lead north, se, and sw.
+
+> se
+
+This is the Oriental Room.  Ancient oriental cave drawings cover the
+walls.  A gently sloping passage leads upward to the north, another
+passage leads se, and a hands and knees crawl leads west.
+
+There is a delicate, precious, ming vase here!
+
+> n
+
+You are following a wide path around the outer edge of a large cavern.
+Far below, through a heavy white mist, strange splashing noises can be
+heard.  The mist rises up through a fissure in the ceiling.  The path
+exits to the south and west.
+
+> w
+
+You are in an alcove.  A small nw path seems to widen after a short
+distance.  An extremely tight tunnel leads east.  It looks like a very
+tight squeeze.  An eerie light can be seen at the other end.
+
+> drop trident
+
+OK
+
+> drop ebony
+
+OK
+
+> drop axe
+
+OK
+
+> drop lantern
+
+OK
+
+> e
+
+You're in Plover Room.
+
+There is an emerald here the size of a plover's egg!
+
+> take emerald
+
+OK
+
+> w
+
+You're in alcove.
+
+There is a lamp shining nearby.
+
+There is a little axe here.
+
+There is a richly-carved ebony statuette here!
+
+There is a jewel-encrusted trident here!
+
+> take lamp
+
+OK
+
+> take axe
+
+OK
+
+> take ebony
+
+OK
+
+> take trident
+
+OK
+
+> nw
+
+You're in misty cavern.
+
+> s
+
+You're in Oriental Room.
+
+There is a delicate, precious, ming vase here!
+
+> take vase
+
+OK
+
+> se
+
+There is a threatening little dwarf in the room with you!
+
+You are in a room whose walls resemble Swiss cheese.  Obvious passages
+go west, east, ne, and nw.  Part of the room is occupied by a large
+bedrock block.
+
+> throw axe
+
+You killed a little dwarf.
+
+You're in Swiss Cheese Room.
+
+There is a little axe here.
+
+> take axe
+
+OK
+
+> e
+
+You are in the Soft Room.  The walls are covered with heavy curtains,
+the floor with a thick pile carpet.  Moss covers the ceiling.
+
+A small velvet pillow lies on the floor.
+
+> take pillow
+
+OK
+
+> w
+
+You're in Swiss Cheese Room.
+
+> drop axe
+
+OK
+
+> ne
+
+You're in Bedquilt.
+
+> e
+
+You are at a complex junction.  A low hands and knees passage from the
+north joins a higher crawl from the east to make a walking passage
+going west.  There is also a large room above.  The air is damp here.
+
+> n
+
+You're in a large room carved out of sedimentary rock.  The floor and
+walls are littered with bits of shells embedded in the stone.  A
+shallow passage proceeds downward, and a somewhat steeper one leads
+up.  A low hands and knees passage enters from the south.
+
+There is an enormous clam here with its shell tightly closed.
+
+> open clam
+
+A glistening pearl falls out of the clam and rolls away.  Goodness,
+this must really be an oyster.  (I never was very good at identifying
+bivalves.)  Whatever it is, it has now snapped shut again.
+
+> s
+
+You're at complex junction.
+
+> u
+
+You are in a large room full of dusty rocks.  There is a big hole in
+the floor.  There are cracks everywhere, and a passage leading east.
+
+> e
+
+You're in dirty passage.
+
+> u
+
+You're in n/s passage above e/w passage.
+
+> n
+
+You're at "Y2".
+
+> off
+
+Your lamp is now off.
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> plugh
+
+>>Foof!<<
+
+You are inside a building, a well house for a large spring.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+There are diamonds here!
+
+There is an enormous ruby here!
+
+There are bars of silver here!
+
+There is a Persian rug spread out on the floor!
+
+There is a large sparkling nugget of gold here!
+
+A precious jade necklace has been dropped here!
+
+There is precious jewelry here!
+
+There are many coins here!
+
+There are some keys on the ground here.
+
+There is food here.
+
+> drop pillow
+
+OK
+
+> drop vase
+
+The vase is now resting, delicately, on a velvet pillow.
+
+> drop trident
+
+OK
+
+> drop emerald
+
+OK
+
+> drop ebony
+
+OK
+
+> take keys
+
+OK
+
+> take food
+
+OK
+
+> plugh
+
+>>Foof!<<
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+A hollow voice says "PLUGH".
+
+> on
+
+Your lamp is now on.
+
+You're at "Y2".
+
+A hollow voice says "PLUGH".
+
+> s
+
+You're in n/s passage above e/w passage.
+
+> d
+
+You're in dirty passage.
+
+> w
+
+You're in dusty rock room.
+
+> d
+
+You're at complex junction.
+
+> n
+
+You're in Shell Room.
+
+There is an enormous oyster here with its shell tightly closed.
+
+> d
+
+You are in a long sloping corridor with ragged sharp walls.
+
+> d
+
+You are in a cul-de-sac about eight feet across.
+
+Off to one side lies a glistening pearl!
+
+> take pearl
+
+OK
+
+> u
+
+You are in a long sloping corridor with ragged sharp walls.
+
+> u
+
+You're in Shell Room.
+
+There is an enormous oyster here with its shell tightly closed.
+
+> s
+
+You're at complex junction.
+
+> w
+
+You're in Bedquilt.
+
+> w
+
+You're in Swiss Cheese Room.
+
+There is a little axe here.
+
+> w
+
+You're at east end of Twopit Room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> w
+
+You are at the west end of the Twopit Room.  There is a large hole in
+the wall above the pit at this end of the room.
+
+Your keen eye spots a severed leporine appendage lying on the ground.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> d
+
+You are at the bottom of the western pit in the Twopit Room.  There is
+a large hole in the wall about 25 feet above you.
+
+There is a gigantic beanstalk stretching all the way up to the hole.
+
+> climb
+
+You clamber up the plant and scurry through the hole at the top.
+
+You're in narrow corridor.
+
+> w
+
+You're in Giant Room.
+
+There is a large nest here, full of golden eggs!
+
+> get eggs
+
+OK
+
+> n
+
+You are at one end of an immense north/south passage.
+
+There is an empty bottle here.
+
+The way north leads through a massive, rusty, iron door.
+
+> take bottle
+
+OK
+
+> n
+
+You're in cavern with waterfall.
+
+> w
+
+You're at steep incline above large room.
+
+> d
+
+You're in large low room.
+
+> sw
+
+You are in a long winding corridor sloping out of sight in both
+directions.
+
+> u
+
+You are on one side of a large, deep chasm.  A heavy white mist rising
+up from below obscures all view of the far side.  A sw path leads away
+from the chasm into a winding corridor.
+
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
+
+A burly troll stands by the bridge and insists you throw him a
+treasure before you may cross.
+
+> toss eggs
+
+The troll catches your treasure and scurries away out of sight.
+
+> ne
+
+You are on the far side of the chasm.  A ne path leads away from the
+chasm on this side.
+
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
+
+The troll is nowhere to be seen.
+
+> ne
+
+You're in a long east/west corridor.  A faint rumbling noise can be
+heard in the distance.
+
+> barren
+
+You are standing at the entrance to a large, barren room.  A notice
+above the entrance reads:  "Caution!  Bear in room!"
+
+> in
+
+You are inside a barren room.  The center of the room is completely
+empty except for some dust.  Marks in the dust lead away toward the
+far end of the room.  The only exit is the way you came in.
+
+There is a ferocious cave bear eyeing you from the far end of the room!
+
+The bear is locked to the wall with a golden chain!
+
+> feed bear
+
+The bear eagerly wolfs down your food, after which he seems to calm
+down considerably and even becomes rather friendly.
+
+> unlock
+
+The chain is now unlocked.
+
+> unlock chain
+
+It was already unlocked.
+
+> take chain
+
+OK
+
+> take bear
+
+OK
+
+> fork
+
+You are being followed by a very large, tame bear.
+
+The path forks here.  The left fork leads northeast.  A dull rumbling
+seems to get louder in that direction.  The right fork leads southeast
+down a gentle slope.  The main corridor enters from the west.
+
+> ne
+
+You are being followed by a very large, tame bear.
+
+The walls are quite warm here.  From the north can be heard a steady
+roar, so loud that the entire cave seems to be trembling.  Another
+passage leads south, and a low crawl goes east.
+
+> e
+
+You are being followed by a very large, tame bear.
+
+You are in a small chamber filled with large boulders.  The walls are
+very warm, causing the air in the room to be almost stifling from the
+heat.  The only exit is a crawl heading west, through which is coming
+a low rumbling.
+
+There are rare spices here!
+
+> take spices
+
+OK
+
+> drop keys
+
+OK
+
+> fork
+
+You are being followed by a very large, tame bear.
+
+You're at fork in path.
+
+> w
+
+You are being followed by a very large, tame bear.
+
+You're in corridor.
+
+> w
+
+You are being followed by a very large, tame bear.
+
+You're on ne side of chasm.
+
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
+
+The troll is nowhere to be seen.
+
+> sw
+
+The troll steps out from beneath the bridge and blocks your way.
+
+You are being followed by a very large, tame bear.
+
+You're on ne side of chasm.
+
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
+
+A burly troll stands by the bridge and insists you throw him a
+treasure before you may cross.
+
+> free bear
+
+The bear lumbers toward the troll, who lets out a startled shriek and
+scurries away.  The bear soon gives up the pursuit and wanders back.
+
+> inven
+
+You are currently holding the following:
+Brass lantern
+Small bottle
+Glistening pearl
+Rare spices
+Golden chain
+
+> sw
+
+You're on sw side of chasm.
+
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
+
+The troll is nowhere to be seen.
+
+> sw
+
+You're in sloping corridor.
+
+> d
+
+You're in large low room.
+
+> se
+
+You're in Oriental Room.
+
+> se
+
+You're in Swiss Cheese Room.
+
+There is a little axe here.
+
+> w
+
+You're at east end of Twopit Room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> d
+
+You're in east pit.
+
+> get oil
+
+Your bottle is now full of oil.
+
+> up
+
+You're at east end of Twopit Room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> e
+
+You are in a room whose walls resemble Swiss cheese.  Obvious passages
+go west, east, ne, and nw.  Part of the room is occupied by a large
+bedrock block.
+
+There is a little axe here.
+
+> take axe
+
+OK
+
+> w
+
+You are at the east end of the Twopit Room.  The floor here is
+littered with thin rock slabs, which make it easy to descend the pits.
+There is a path here bypassing the pits to connect passages from east
+and west.  There are holes all over, but the only big one is on the
+wall directly over the west pit where you can't get to it.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> w
+
+You're at west end of Twopit Room.
+
+Your keen eye spots a severed leporine appendage lying on the ground.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> d
+
+You're in west pit.
+
+There is a gigantic beanstalk stretching all the way up to the hole.
+
+> climb
+
+You clamber up the plant and scurry through the hole at the top.
+
+You're in narrow corridor.
+
+> w
+
+You're in Giant Room.
+
+> fee
+
+OK
+
+> fie
+
+OK
+
+> foe
+
+OK
+
+> foo
+
+There is a large nest here, full of golden eggs!
+
+> take eggs
+
+OK
+
+> s
+
+You're in narrow corridor.
+
+> d
+
+You're in west pit.
+
+There is a gigantic beanstalk stretching all the way up to the hole.
+
+> u
+
+You're at west end of Twopit Room.
+
+Your keen eye spots a severed leporine appendage lying on the ground.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> w
+
+You're in Slab Room.
+
+> u
+
+You are in a secret n/s canyon above a large room.
+
+> s
+
+You are in a secret canyon which exits to the north and east.
+
+The body of a huge green dead dragon is lying off to one side.
+
+> e
+
+You're in secret e/w canyon above tight canyon.
+
+> e
+
+You're in Hall of Mt King.
+
+> n
+
+You're in n/s passage above e/w passage.
+
+> n
+
+You're at "Y2".
+
+A hollow voice says "PLUGH".
+
+> off
+
+Your lamp is now off.
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> plugh
+
+>>Foof!<<
+
+You're inside building.
+
+There is a richly-carved ebony statuette here!
+
+There is an emerald here the size of a plover's egg!
+
+There is a jewel-encrusted trident here!
+
+There is a delicate, precious, ming vase here!
+
+A small velvet pillow lies on the floor.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+There are diamonds here!
+
+There is an enormous ruby here!
+
+There are bars of silver here!
+
+There is a Persian rug spread out on the floor!
+
+There is a large sparkling nugget of gold here!
+
+A precious jade necklace has been dropped here!
+
+There is precious jewelry here!
+
+There are many coins here!
+
+> drop eggs
+
+OK
+
+> drop pearl
+
+OK
+
+> drop spices
+
+OK
+
+> drop chain
+
+OK
+
+> take rug
+
+OK
+
+> take ruby
+
+OK
+
+> take emerald
+
+OK
+
+> out
+
+You're in front of building.
+
+> w
+
+You have walked up a hill, still in the forest.  The road slopes back
+down the other side of the hill.  There is a building in the distance.
+
+> n
+
+You are wandering aimlessly through the forest.
+
+> n
+
+You are wandering aimlessly through the forest.
+
+> n
+
+The forest thins out here to reveal a steep cliff.  There is no way
+down, but a small ledge can be seen to the west across the chasm.
+
+A small urn is embedded in the rock.
+
+> inven
+
+You are currently holding the following:
+Brass lantern
+Small bottle
+Oil in the bottle
+Dwarf's axe
+Egg-sized emerald
+Persian rug
+Giant ruby
+
+> fill urn
+
+Your bottle is now empty and the urn is full of oil.
+
+> light urn
+
+The urn is now lit.
+
+> rub urn
+
+As you rub the urn, there is a flash of light and a genie appears.
+His aspect is stern as he advises: "One who wouldst traffic in
+precious stones must first learn to recognize the signals thereof."
+He wrests the urn from the stone, leaving a small cavity.  Turning to
+face you again, he fixes you with a steely eye and intones: "Caution!"
+Genie and urn vanish in a cloud of amber smoke.  The smoke condenses
+to form a rare amber gemstone, resting in the cavity in the rock.
+
+> take amber
+
+OK
+
+> drop rug
+
+OK
+
+> drop emerald
+
+The gem fits easily into the cavity.
+
+The Persian rug stiffens and rises a foot or so off the ground.
+
+> fly rug
+
+You board the Persian rug, which promptly whisks you across the chasm.
+You have time for a fleeting glimpse of a two thousand foot drop to a
+mighty river; then you find yourself on the other side.
+
+You are on a small ledge on one face of a sheer cliff.  There are no
+paths away from the ledge.  Across the chasm is a small clearing
+surrounded by forest.
+
+There is a Persian rug here, hovering in mid-air!
+
+A brilliant blue star sapphire is here!
+
+> take sapphire
+
+OK
+
+> fly rug
+
+The rug ferries you back across the chasm.
+
+You're at cliff.
+
+There is an emerald resting in a small cavity in the rock!
+
+There is a Persian rug here, hovering in mid-air!
+
+> take emerald
+
+OK
+
+> drop ruby
+
+The gem fits easily into the cavity.
+
+The Persian rug settles gently to the ground.
+
+> take rug
+
+OK
+
+> drop bottle
+
+OK
+
+> take ruby
+
+OK
+
+> e
+
+You are wandering aimlessly through the forest.
+
+> s
+
+You are wandering aimlessly through the forest.
+
+> e
+
+You're at hill in road.
+
+> e
+
+You are standing at the end of a road before a small brick building.
+Around you is a forest.  A small stream flows out of the building and
+down a gully.
+
+> in
+
+Tsk!  A wizard wouldn't have to take 350 turns.  This is going to cost
+you a couple of points.
+
+You're inside building.
+
+There is a golden chain lying in a heap on the floor!
+
+There are rare spices here!
+
+Off to one side lies a glistening pearl!
+
+There is a large nest here, full of golden eggs!
+
+There is a richly-carved ebony statuette here!
+
+There is a jewel-encrusted trident here!
+
+There is a delicate, precious, ming vase here!
+
+A small velvet pillow lies on the floor.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+There are diamonds here!
+
+There are bars of silver here!
+
+There is a large sparkling nugget of gold here!
+
+A precious jade necklace has been dropped here!
+
+There is precious jewelry here!
+
+There are many coins here!
+
+> drop ruby
+
+OK
+
+> drop sapphire
+
+OK
+
+> drop amber
+
+OK
+
+> drop rug
+
+OK
+
+> look
+
+Sorry, but I am not allowed to give more detail.  I will repeat the
+long description of your location.
+
+You are inside a building, a well house for a large spring.
+
+There is a Persian rug spread out on the floor!
+
+There is a rare amber gemstone here!
+
+A brilliant blue star sapphire is here!
+
+There is an enormous ruby here!
+
+There is a golden chain lying in a heap on the floor!
+
+There are rare spices here!
+
+Off to one side lies a glistening pearl!
+
+There is a large nest here, full of golden eggs!
+
+There is a richly-carved ebony statuette here!
+
+There is a jewel-encrusted trident here!
+
+There is a delicate, precious, ming vase here!
+
+A small velvet pillow lies on the floor.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+There are diamonds here!
+
+There are bars of silver here!
+
+There is a large sparkling nugget of gold here!
+
+A precious jade necklace has been dropped here!
+
+There is precious jewelry here!
+
+There are many coins here!
+
+> plugh
+
+>>Foof!<<
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> on
+
+Your lamp is now on.
+
+You are in a large room, with a passage to the south, a passage to the
+west, and a wall of broken rock to the east.  There is a large "Y2" on
+a rock in the room's center.
+
+> s
+
+You are in a low n/s passage at a hole in the floor.  The hole goes
+down to an e/w passage.
+
+> s
+
+You're in Hall of Mt King.
+
+> u
+
+You're in Hall of Mists.
+
+Rough stone steps lead up the dome.
+
+> w
+
+Out from the shadows behind you pounces a bearded pirate!  "Har, har,"
+he chortles, "I'll just take all this booty and hide it away with me
+chest deep in the maze!"  He snatches your treasure and vanishes into
+the gloom.
+
+You're on east bank of fissure.
+
+A three foot black rod with a rusty star on an end lies nearby.
+
+A crystal bridge spans the fissure.
+
+> w
+
+You're on west bank of fissure.
+
+A crystal bridge spans the fissure.
+
+> w
+
+You're at west end of Hall of Mists.
+
+> s
+
+You are in a maze of twisty little passages, all alike.
+
+> e
+
+You are in a maze of twisty little passages, all alike.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+One sharp nasty knife is thrown at you!
+
+It misses!
+
+You are in a maze of twisty little passages, all alike.
+
+> throw axe
+
+You killed a little dwarf.
+
+You are in a maze of twisty little passages, all alike.
+
+There is a little axe here.
+
+> take axe
+
+OK
+
+> s
+
+You are in a maze of twisty little passages, all alike.
+
+> s
+
+You are in a maze of twisty little passages, all alike.
+
+> n
+
+You are in a maze of twisty little passages, all alike.
+
+> e
+
+You are on the brink of a thirty foot pit with a massive orange column
+down one wall.  You could climb down here but you could not get back
+up.  The maze continues at this level.
+
+> e
+
+You are in a maze of twisty little passages, all alike.
+
+> nw
+
+Dead end
+
+There is an emerald here the size of a plover's egg!
+
+The pirate's treasure chest is here!
+
+> take emerald
+
+OK
+
+> take chest
+
+OK
+
+> se
+
+You are in a maze of twisty little passages, all alike.
+
+> n
+
+You're at brink of pit.
+
+> d
+
+You're in bird chamber.
+
+> e
+
+You are in an awkward sloping east/west canyon.
+
+> e
+
+You're in debris room.
+
+> off
+
+Your lamp is now off.
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> xyzzy
+
+>>Foof!<<
+
+You're inside building.
+
+There is a Persian rug spread out on the floor!
+
+There is a rare amber gemstone here!
+
+A brilliant blue star sapphire is here!
+
+There is an enormous ruby here!
+
+There is a golden chain lying in a heap on the floor!
+
+There are rare spices here!
+
+Off to one side lies a glistening pearl!
+
+There is a large nest here, full of golden eggs!
+
+There is a richly-carved ebony statuette here!
+
+There is a jewel-encrusted trident here!
+
+There is a delicate, precious, ming vase here!
+
+A small velvet pillow lies on the floor.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+There are diamonds here!
+
+There are bars of silver here!
+
+There is a large sparkling nugget of gold here!
+
+A precious jade necklace has been dropped here!
+
+There is precious jewelry here!
+
+There are many coins here!
+
+> drop emerald
+
+OK
+
+> drop chest
+
+OK
+
+> plugh
+
+>>Foof!<<
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> on
+
+Your lamp is now on.
+
+You're at "Y2".
+
+A hollow voice says "PLUGH".
+
+> s
+
+You're in n/s passage above e/w passage.
+
+> d
+
+Your lamp is getting dim.  You'd best start wrapping this up, unless
+you can find some fresh batteries.  I seem to recall there's a vending
+machine in the maze.  Bring some coins with you.
+
+You're in dirty passage.
+
+> w
+
+You're in dusty rock room.
+
+> d
+
+You're at complex junction.
+
+> e
+
+You are in an anteroom leading to a large passage to the east.  Small
+passages go west and up.  The remnants of recent digging are evident.
+A sign in midair here says "Cave under construction beyond this point.
+Proceed at own risk.  [Witt Construction Company]"
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> take magazine
+
+OK
+
+> e
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+> drop magazine
+
+OK
+
+> e
+
+You have crawled around in some little holes and wound up back in the
+main passage.
+
+You're at Witt's End.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> e
+
+You have crawled around in some little holes and wound up back in the
+main passage.
+
+You're at Witt's End.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> e
+
+You have crawled around in some little holes and wound up back in the
+main passage.
+
+You're at Witt's End.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> e
+
+You have crawled around in some little holes and wound up back in the
+main passage.
+
+You're at Witt's End.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> e
+
+You have crawled around in some little holes and wound up back in the
+main passage.
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> e
+
+You have crawled around in some little holes and wound up back in the
+main passage.
+
+You're at Witt's End.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> e
+
+You have crawled around in some little holes and wound up back in the
+main passage.
+
+You're at Witt's End.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> e
+
+You have crawled around in some little holes and wound up back in the
+main passage.
+
+You're at Witt's End.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> e
+
+You have crawled around in some little holes and wound up back in the
+main passage.
+
+You're at Witt's End.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> e
+
+You have crawled around in some little holes and wound up back in the
+main passage.
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> e
+
+You have crawled around in some little holes and wound up back in the
+main passage.
+
+You're at Witt's End.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> e
+
+You have crawled around in some little holes and wound up back in the
+main passage.
+
+You're at Witt's End.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> e
+
+You have crawled around in some little holes and wound up back in the
+main passage.
+
+You're at Witt's End.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> e
+
+You have crawled around in some little holes and wound up back in the
+main passage.
+
+You're at Witt's End.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> e
+
+You have crawled around in some little holes and wound up back in the
+main passage.
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> e
+
+You're in anteroom.
+
+> u
+
+You are at a complex junction.  A low hands and knees passage from the
+north joins a higher crawl from the east to make a walking passage
+going west.  There is also a large room above.  The air is damp here.
+
+> u
+
+A sepulchral voice reverberating through the cave, says, "Cave closing
+soon.  All adventurers exit immediately through main office."
+
+You're in dusty rock room.
+
+> e
+
+You're in dirty passage.
+
+> u
+
+You're in n/s passage above e/w passage.
+
+> n
+
+You're at "Y2".
+
+> plover
+
+>>Foof!<<
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in a small chamber lit by an eerie green light.  An extremely
+narrow tunnel exits to the west.  A dark corridor leads ne.
+
+> e
+
+Your lamp has run out of power.
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in a small chamber lit by an eerie green light.  An extremely
+narrow tunnel exits to the west.  A dark corridor leads ne.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in a small chamber lit by an eerie green light.  An extremely
+narrow tunnel exits to the west.  A dark corridor leads ne.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in a small chamber lit by an eerie green light.  An extremely
+narrow tunnel exits to the west.  A dark corridor leads ne.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in a small chamber lit by an eerie green light.  An extremely
+narrow tunnel exits to the west.  A dark corridor leads ne.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in a small chamber lit by an eerie green light.  An extremely
+narrow tunnel exits to the west.  A dark corridor leads ne.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in a small chamber lit by an eerie green light.  An extremely
+narrow tunnel exits to the west.  A dark corridor leads ne.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in a small chamber lit by an eerie green light.  An extremely
+narrow tunnel exits to the west.  A dark corridor leads ne.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in a small chamber lit by an eerie green light.  An extremely
+narrow tunnel exits to the west.  A dark corridor leads ne.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> e
+
+There is no way to go that direction.
+
+You're in Plover Room.
+
+> cave
+
+I need more detailed instructions to do that.
+
+You're in Plover Room.
+
+> e
+
+The sepulchral voice intones, "The cave is now closed."  As the echoes
+fade, there is a blinding flash of light (and a small puff of orange
+smoke). . . .    As your eyes refocus, you look around and find...
+
+You are at the northeast end of an immense room, even larger than the
+Giant Room.  It appears to be a repository for the "Adventure"
+program.  Massive torches far overhead bathe the room with smoky
+yellow light.  Scattered about you can be seen a pile of bottles (all
+of them empty), a nursery of young beanstalks murmuring quietly, a bed
+of oysters, a bundle of black rods with rusty stars on their ends, and
+a collection of brass lanterns.  Off to one side a great many dwarves
+are sleeping on the floor, snoring loudly.  A notice nearby reads: "Do
+not disturb the dwarves!"  An immense mirror is hanging against one
+wall, and stretches to the other end of the room, where various other
+sundry objects can be glimpsed dimly in the distance.
+
+> take oyster
+
+OK
+
+Interesting.  There seems to be something written on the underside of
+the oyster.
+
+> unlock oyster
+
+I advise you to put down the oyster before opening it.  >WRENCH!<
+
+> 
+You scored 389 out of a possible 430, using 466 turns.
+
+Your score puts you in Master Adventurer Class B.
+
+To achieve the next higher rating, you need 22 more points.
diff --git a/tests/foofum.log b/tests/oysterbug.log
similarity index 63%
rename from tests/foofum.log
rename to tests/oysterbug.log
index f713fc7..0337967 100644
--- a/tests/foofum.log
+++ b/tests/oysterbug.log
@@ -1,4 +1,7 @@
-## Test processing of fee fie foe fum
+## Demonstrate fix of buggy response to unlocking oyster while carrying it.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE This fails due to a known bug in advent430
 n
 seed 1838473132
 in
@@ -173,6 +176,7 @@ take water
 s
 s
 s
+break mirror
 s
 d
 s
@@ -190,6 +194,7 @@ d
 climb
 w
 n
+unlock
 oil door
 drop bottle
 n
@@ -272,6 +277,7 @@ ne
 barren
 in
 feed bear
+unlock
 unlock chain
 take chain
 take bear
@@ -305,6 +311,164 @@ w
 fee
 fie
 foe
-fum
-quit
-yes
+foo
+take eggs
+s
+d
+u
+w
+u
+s
+e
+e
+n
+n
+off
+plugh
+drop eggs
+drop pearl
+drop spices
+drop chain
+take rug
+take ruby
+take emerald
+out
+w
+n
+n
+n
+inven
+fill urn
+light urn
+rub urn
+take amber
+drop rug
+drop emerald
+fly rug
+take sapphire
+fly rug
+take emerald
+drop ruby
+take rug
+drop bottle
+take ruby
+e
+s
+e
+e
+in
+drop ruby
+drop sapphire
+drop amber
+drop rug
+look
+plugh
+on
+s
+s
+u
+w
+w
+w
+s
+e
+s
+throw axe
+take axe
+s
+s
+n
+e
+e
+nw
+take emerald
+take chest
+se
+n
+d
+e
+e
+off
+xyzzy
+drop emerald
+drop chest
+plugh
+on
+s
+d
+w
+d
+e
+take magazine
+e
+drop magazine
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+u
+u
+e
+u
+n
+plover
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+e
+cave
+e
+take oyster
+unlock oyster
diff --git a/tests/panic.chk b/tests/panic.chk
index bd23880..e44e632 100644
--- a/tests/panic.chk
+++ b/tests/panic.chk
@@ -2631,7 +2631,7 @@ The grate is locked.
 A mysterious recorded voice groans into life and announces:
    "This exit is closed.  Please leave via main office."
 
-
+> 
 You scored 365 out of a possible 430, using 422 turns.
 
 Your score puts you in Master Adventurer Class C.
diff --git a/tests/panic.log b/tests/panic.log
index de6f2c5..155669e 100644
--- a/tests/panic.log
+++ b/tests/panic.log
@@ -1,4 +1,6 @@
 ## Panic test - attempt to unlock grate after game closed.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
diff --git a/tests/panic2.chk b/tests/panic2.chk
index ac42e46..db66581 100644
--- a/tests/panic2.chk
+++ b/tests/panic2.chk
@@ -2592,7 +2592,7 @@ A mysterious recorded voice groans into life and announces:
 
 You're at "Y2".
 
-
+> 
 You scored 365 out of a possible 430, using 414 turns.
 
 Your score puts you in Master Adventurer Class C.
diff --git a/tests/panic2.log b/tests/panic2.log
index f95aa5b..1f70a46 100644
--- a/tests/panic2.log
+++ b/tests/panic2.log
@@ -1,4 +1,6 @@
 ## Panic test - attempt to xyzzy out after game is closed.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
diff --git a/tests/pirate_carry.chk b/tests/pirate_carry.chk
index f2e7893..72b1681 100644
--- a/tests/pirate_carry.chk
+++ b/tests/pirate_carry.chk
@@ -316,7 +316,7 @@ You are on the west side of the fissure in the Hall of Mists.
 
 A crystal bridge spans the fissure.
 
-
+> 
 You scored 67 out of a possible 430, using 43 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/pirate_carry.log b/tests/pirate_carry.log
index c84b393..733d03f 100644
--- a/tests/pirate_carry.log
+++ b/tests/pirate_carry.log
@@ -1,4 +1,6 @@
 ## Check that pirate steals loose treasure from ground (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1837473132
 in
@@ -44,4 +46,4 @@ e
 u
 w
 wave rod
-w
\ No newline at end of file
+w
diff --git a/tests/pirate_pyramid.chk b/tests/pirate_pyramid.chk
index a7ac101..873cdaa 100644
--- a/tests/pirate_pyramid.chk
+++ b/tests/pirate_pyramid.chk
@@ -356,7 +356,7 @@ You are currently holding the following:
 Brass lantern
 Wicker cage
 
-
+> 
 You scored 69 out of a possible 430, using 50 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/pirate_pyramid.log b/tests/pirate_pyramid.log
index 1d16702..83f7a6d 100644
--- a/tests/pirate_pyramid.log
+++ b/tests/pirate_pyramid.log
@@ -1,4 +1,6 @@
 ## Pirate mustn't take pyramid from plover/dark rooms (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1830473132
 in
diff --git a/tests/pirate_spotted.chk b/tests/pirate_spotted.chk
index 5cfc3c4..e8fad72 100644
--- a/tests/pirate_spotted.chk
+++ b/tests/pirate_spotted.chk
@@ -984,7 +984,7 @@ There is a huge beanstalk growing out of the west pit up to the hole.
 You are at the bottom of the eastern pit in the Twopit Room.  There is
 a small pool of oil in one corner of the pit.
 
-> g oil
+> get oil
 
 Your bottle is now full of oil.
 
@@ -1351,7 +1351,7 @@ You're in Giant Room.
 
 There is a large nest here, full of golden eggs!
 
-> g
+> get
 
 OK
 
@@ -1547,7 +1547,7 @@ There is a huge beanstalk growing out of the west pit up to the hole.
 
 You're in east pit.
 
-> g oil
+> get oil
 
 Your bottle is now full of oil.
 
@@ -1839,7 +1839,7 @@ You're in Hall of Mists.
 
 Rough stone steps lead up the dome.
 
-
+> 
 You scored 123 out of a possible 430, using 295 turns.
 
 You have achieved the rating: "Experienced Adventurer".
diff --git a/tests/pirate_spotted.log b/tests/pirate_spotted.log
index 1eeca5d..a0ed6f5 100644
--- a/tests/pirate_spotted.log
+++ b/tests/pirate_spotted.log
@@ -1,4 +1,6 @@
 ## Spot pirate to manifest chest before last treasure (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
@@ -156,7 +158,7 @@ u
 drop appen
 e
 d
-g oil
+get oil
 u
 w
 d
@@ -220,7 +222,7 @@ w
 d
 climb
 w
-g
+get
 n
 take bottl
 n
@@ -250,7 +252,7 @@ se
 se
 w
 d
-g oil
+get oil
 u
 e
 w
diff --git a/tests/pitfall.log b/tests/pitfall.log
index 6c5adc7..cd16da9 100644
--- a/tests/pitfall.log
+++ b/tests/pitfall.log
@@ -1,5 +1,7 @@
 ## Death by pitfall
-# Die 3 times so we can cover all the opituary messages
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+# Die 3 times so we can cover all the obituary messages
 n
 seed 780351908
 enter building
diff --git a/tests/plover.chk b/tests/plover.chk
index 67e58af..c59ae86 100644
--- a/tests/plover.chk
+++ b/tests/plover.chk
@@ -1169,7 +1169,7 @@ Egg-sized emerald
 
 It is now pitch dark.  If you proceed you will likely fall into a pit.
 
-
+> 
 You scored 169 out of a possible 430, using 187 turns.
 
 You have achieved the rating: "Experienced Adventurer".
diff --git a/tests/plover.log b/tests/plover.log
index 740ed16..47d3ec8 100644
--- a/tests/plover.log
+++ b/tests/plover.log
@@ -1,4 +1,6 @@
 ## Test access to emerald room and plover teleport
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56
 n
 seed 1495951709
diff --git a/tests/reach_ledge_short.chk b/tests/reach_ledge_short.chk
index c5e083e..7c02c64 100644
--- a/tests/reach_ledge_short.chk
+++ b/tests/reach_ledge_short.chk
@@ -555,11 +555,9 @@ The ogre, distracted by your rush, is struck by the knife.  With a
 blood-curdling yell he turns and bounds after the dwarf, who flees
 in panic.  You are left alone in the room.
 
->  
+> z
 
-I don't know how to apply that word here.
-
-You are in a large chamber with passages to the west and north.
+OK
 
 > s
 
@@ -622,10 +620,6 @@ A crystal bridge spans the fissure.
 
 There is a threatening little dwarf in the room with you!
 
-One sharp nasty knife is thrown at you!
-
-It misses!
-
 You are at one end of a vast hall stretching forward out of sight to
 the west.  There are openings to either side.  Nearby, a wide stone
 staircase leads downward.  The hall is filled with wisps of white mist
@@ -657,12 +651,20 @@ A cheerful little bird is sitting here singing.
 
 > n
 
+There is a threatening little dwarf in the room with you!
+
+One sharp nasty knife is thrown at you!
+
+It misses!
+
 You're in n/s passage above e/w passage.
 
 There are bars of silver here!
 
 > n
 
+There is a threatening little dwarf in the room with you!
+
 You are in a large room, with a passage to the south, a passage to the
 west, and a wall of broken rock to the east.  There is a large "Y2" on
 a rock in the room's center.
@@ -693,14 +695,14 @@ There is food here.
 
 It is now pitch dark.  If you proceed you will likely fall into a pit.
 
+A hollow voice says "PLUGH".
+
 > on
 
 Your lamp is now on.
 
 You're at "Y2".
 
-A hollow voice says "PLUGH".
-
 > s
 
 You are in a low n/s passage at a hole in the floor.  The hole goes
@@ -716,12 +718,20 @@ A cheerful little bird is sitting here singing.
 
 > u
 
+There is a threatening little dwarf in the room with you!
+
+One sharp nasty knife is thrown at you!
+
+It misses!
+
 You're in Hall of Mists.
 
 Rough stone steps lead up the dome.
 
 > n
 
+There is a threatening little dwarf in the room with you!
+
 You are in the Hall of the Mountain King, with passages off in all
 directions.
 
@@ -729,12 +739,16 @@ A cheerful little bird is sitting here singing.
 
 > n
 
+There is a threatening little dwarf in the room with you!
+
 You're in n/s passage above e/w passage.
 
 There are bars of silver here!
 
 > d
 
+There is a threatening little dwarf in the room with you!
+
 You are in a dirty broken passage.  To the east is a crawl.  To the
 west is a large passage.  Above you is a hole to another passage.
 
@@ -747,7 +761,13 @@ To explore at random select north, south, up, or down.
 
 > throw axe
 
-You killed a little dwarf.
+You attack a little dwarf, but he dodges out of the way.
+
+There is a threatening little dwarf in the room with you!
+
+One sharp nasty knife is thrown at you!
+
+It misses!
 
 You're in Bedquilt.
 
@@ -755,10 +775,12 @@ There is a little axe here.
 
 > take
 
-OK
+Take what?
 
 > slab
 
+There is a threatening little dwarf in the room with you!
+
 You are in a large low circular chamber whose floor is an immense slab
 fallen from the ceiling (Slab Room).  East and west there once were
 large passages, but they are now filled with boulders.  Low small
@@ -767,11 +789,15 @@ around the boulders.
 
 > s
 
+There is a threatening little dwarf in the room with you!
+
 You are at the west end of the Twopit Room.  There is a large hole in
 the wall above the pit at this end of the room.
 
 > d
 
+There is a threatening little dwarf in the room with you!
+
 You are at the bottom of the western pit in the Twopit Room.  There is
 a large hole in the wall about 25 feet above you.
 
@@ -781,6 +807,12 @@ There is a tiny little plant in the pit, murmuring "water, water, ..."
 
 The plant spurts into furious growth for a few seconds.
 
+There is a threatening little dwarf in the room with you!
+
+One sharp nasty knife is thrown at you!
+
+It misses!
+
 You're in west pit.
 
 There is a 12-foot-tall beanstalk stretching up out of the pit,
@@ -788,20 +820,28 @@ bellowing "WATER!! WATER!!"
 
 > u
 
+There is a threatening little dwarf in the room with you!
+
 You're at west end of Twopit Room.
 
 The top of a 12-foot-tall beanstalk is poking out of the west pit.
 
 > west
 
+There is a threatening little dwarf in the room with you!
+
 You're in Slab Room.
 
 > u
 
+There is a threatening little dwarf in the room with you!
+
 You are in a secret n/s canyon above a large room.
 
 > reser
 
+There is a threatening little dwarf in the room with you!
+
 You are at the edge of a large underground reservoir.  An opaque cloud
 of white mist fills the room and rises rapidly upward.  The lake is
 fed by a stream, which tumbles out of a hole in the wall about 10 feet
@@ -814,12 +854,16 @@ The waters have parted to form a narrow path across the reservoir.
 
 > n
 
+There is a threatening little dwarf in the room with you!
+
 You are walking across the bottom of the reservoir.  Walls of water
 rear up on either side.  The roar of the water cascading past is
 nearly deafening, and the mist is so thick you can barely see.
 
 > n
 
+There is a threatening little dwarf in the room with you!
+
 You are at the northern edge of the reservoir.  A northwest passage
 leads sharply up from here.
 
@@ -827,14 +871,20 @@ The waters have parted to form a narrow path across the reservoir.
 
 > u
 
+There is a threatening little dwarf in the room with you!
+
 You are scrambling along a treacherously steep, rocky passage.
 
 > u
 
+There is a threatening little dwarf in the room with you!
+
 You are on a very steep incline, which widens at it goes upward.
 
 > u
 
+There is a threatening little dwarf in the room with you!
+
 You are at the base of a nearly vertical cliff.  There are some
 slim footholds which would enable you to climb up, but it looks
 extremely dangerous.  Here at the base of the cliff lie the remains
@@ -842,642 +892,222 @@ of several earlier adventurers who apparently failed to make it.
 
 > u
 
-You are climbing along a nearly vertical cliff.
-
-> e
-
-There is no way to go that direction.
+There is a threatening little dwarf in the room with you!
 
 You are climbing along a nearly vertical cliff.
 
-> w
+> e
 
 There is no way to go that direction.
 
-You are climbing along a nearly vertical cliff.
+There is a threatening little dwarf in the room with you!
 
-> d
+One sharp nasty knife is thrown at you!
 
-You're at base of cliff.
+It gets you!
 
-> d
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
-You are on a very steep incline, which widens at it goes upward.
+> w
 
-> d
+Please answer the question.
 
-You are scrambling along a treacherously steep, rocky passage.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
 > d
 
-You're north of reservoir.
+Please answer the question.
 
-The waters have parted to form a narrow path across the reservoir.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
 > d
 
-There is no way to go that direction.
-
-You're north of reservoir.
-
-The waters have parted to form a narrow path across the reservoir.
-
-> take water
-
-Your bottle is now full of water.
-
-> s
-
-You're at bottom of reservoir.
-
-> s
-
-You're at reservoir.
-
-The waters have parted to form a narrow path across the reservoir.
-
-> s
-
-You are in a north/south canyon about 25 feet across.  The floor is
-covered by white mist seeping in from the north.  The walls extend
-upward for well over 100 feet.  Suspended from some unseen point far
-above you, an enormous two-sided mirror is hanging parallel to and
-midway between the canyon walls.  (The mirror is obviously provided
-for the use of the dwarves who, as you know, are extremely vain.)  A
-small window can be seen in either wall, some fifty feet up.
-
-> s
+Please answer the question.
 
-You are in a secret n/s canyon above a large room.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
 > d
 
-You're in Slab Room.
+Please answer the question.
 
-> s
-
-You're at west end of Twopit Room.
-
-The top of a 12-foot-tall beanstalk is poking out of the west pit.
-
-> d
-
-You're in west pit.
-
-There is a 12-foot-tall beanstalk stretching up out of the pit,
-bellowing "WATER!! WATER!!"
-
-> water plant
-
-The plant grows explosively, almost filling the bottom of the pit.
-
-You're in west pit.
-
-There is a gigantic beanstalk stretching all the way up to the hole.
-
-> u
-
-You're at west end of Twopit Room.
-
-There is a huge beanstalk growing out of the west pit up to the hole.
-
-> e
-
-You are at the east end of the Twopit Room.  The floor here is
-littered with thin rock slabs, which make it easy to descend the pits.
-There is a path here bypassing the pits to connect passages from east
-and west.  There are holes all over, but the only big one is on the
-wall directly over the west pit where you can't get to it.
-
-There is a huge beanstalk growing out of the west pit up to the hole.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
 > d
 
-You are at the bottom of the eastern pit in the Twopit Room.  There is
-a small pool of oil in one corner of the pit.
-
-> get oil
-
-Your bottle is now full of oil.
-
-> u
-
-You're at east end of Twopit Room.
-
-There is a huge beanstalk growing out of the west pit up to the hole.
+Please answer the question.
 
-> west
-
-You're at west end of Twopit Room.
-
-There is a huge beanstalk growing out of the west pit up to the hole.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
 > d
 
-You're in west pit.
-
-There is a gigantic beanstalk stretching all the way up to the hole.
-
-> climb
-
-You clamber up the plant and scurry through the hole at the top.
+Please answer the question.
 
-You are in a long, narrow corridor stretching out of sight to the
-west.  At the eastern end is a hole through which you can see a
-profusion of leaves.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
-> west
+> take water
 
-You are in the Giant Room.  The ceiling here is too high up for your
-lamp to show it.  Cavernous passages lead east, north, and south.  On
-the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic].
+Please answer the question.
 
-There is a large nest here, full of golden eggs!
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
-> n
+> s
 
-You are at one end of an immense north/south passage.
+Please answer the question.
 
-The way north is barred by a massive, rusty, iron door.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
-> oil door
+> s
 
-The oil has freed up the hinges so that the door will now move,
-although it requires some effort.
+Please answer the question.
 
-> drop bottl
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
-OK
+> s
 
-> n
+Please answer the question.
 
-You are in a magnificent cavern with a rushing stream, which cascades
-over a sparkling waterfall into a roaring whirlpool which disappears
-through a hole in the floor.  Passages exit to the south and west.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
-There is a jewel-encrusted trident here!
+> s
 
-> west
+Please answer the question.
 
-You are at the top of a steep incline above a large room.  You could
-climb down here, but you would not be able to climb up.  There is a
-passage leading back to the north.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
 > d
 
-You are in a large low room.  Crawls lead north, se, and sw.
+Please answer the question.
 
-> se
-
-This is the Oriental Room.  Ancient oriental cave drawings cover the
-walls.  A gently sloping passage leads upward to the north, another
-passage leads se, and a hands and knees crawl leads west.
-
-There is a delicate, precious, ming vase here!
-
-> n
-
-You are following a wide path around the outer edge of a large cavern.
-Far below, through a heavy white mist, strange splashing noises can be
-heard.  The mist rises up through a fissure in the ceiling.  The path
-exits to the south and west.
-
-> west
-
-You are in an alcove.  A small nw path seems to widen after a short
-distance.  An extremely tight tunnel leads east.  It looks like a very
-tight squeeze.  An eerie light can be seen at the other end.
-
-> drop axe
-
-OK
-
-> drop lante
-
-OK
-
-> e
-
-You're in Plover Room.
-
-There is an emerald here the size of a plover's egg!
-
-> take emera
-
-OK
-
-> west
-
-You're in alcove.
-
-There is a lamp shining nearby.
-
-There is a little axe here.
-
-> take lamp
-
-OK
-
-> take
-
-OK
-
-> nw
-
-You're in misty cavern.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
 > s
 
-You're in Oriental Room.
-
-There is a delicate, precious, ming vase here!
-
-> e
-
-There is no way to go that direction.
-
-You're in Oriental Room.
-
-There is a delicate, precious, ming vase here!
-
-> se
-
-There is a threatening little dwarf in the room with you!
-
-You are in a room whose walls resemble Swiss cheese.  Obvious passages
-go west, east, ne, and nw.  Part of the room is occupied by a large
-bedrock block.
-
-> throw axe
-
-You killed a little dwarf.
-
-You're in Swiss Cheese Room.
-
-There is a little axe here.
-
-> e
-
-You are in the Soft Room.  The walls are covered with heavy curtains,
-the floor with a thick pile carpet.  Moss covers the ceiling.
+Please answer the question.
 
-A small velvet pillow lies on the floor.
-
-> west
-
-You're in Swiss Cheese Room.
-
-There is a little axe here.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
 > d
 
-There is no way to go that direction.
-
-You're in Swiss Cheese Room.
-
-There is a little axe here.
-
-> ne
-
-You're in Bedquilt.
-
-> e
-
-You are at a complex junction.  A low hands and knees passage from the
-north joins a higher crawl from the east to make a walking passage
-going west.  There is also a large room above.  The air is damp here.
+Please answer the question.
 
-> u
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
-You are in a large room full of dusty rocks.  There is a big hole in
-the floor.  There are cracks everywhere, and a passage leading east.
+> water plant
 
-> e
+Please answer the question.
 
-You're in dirty passage.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
 > u
 
-You're in n/s passage above e/w passage.
-
-There are bars of silver here!
-
-> n
-
-You're at "Y2".
-
-> plugh
-
->>Foof!<<
-
-You are inside a building, a well house for a large spring.
-
-There is a Persian rug spread out on the floor!
-
-There are some keys on the ground here.
-
-There is food here.
-
-> take key
-
-OK
-
-> take food
-
-OK
-
-> plugh
-
->>Foof!<<
-
-You're at "Y2".
-
-> s
-
-You're in n/s passage above e/w passage.
-
-There are bars of silver here!
-
-> d
-
-You're in dirty passage.
-
-> west
-
-You're in dusty rock room.
-
-> d
+Please answer the question.
 
-You're at complex junction.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
-> n
+> e
 
-You're in a large room carved out of sedimentary rock.  The floor and
-walls are littered with bits of shells embedded in the stone.  A
-shallow passage proceeds downward, and a somewhat steeper one leads
-up.  A low hands and knees passage enters from the south.
+Please answer the question.
 
-There is an enormous clam here with its shell tightly closed.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
 > d
 
-You are in a long sloping corridor with ragged sharp walls.
+Please answer the question.
 
-> d
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
-You are in a cul-de-sac about eight feet across.
+> get oil
 
-> u
+Please answer the question.
 
-You are in a long sloping corridor with ragged sharp walls.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
 > u
 
-You're in Shell Room.
-
-There is an enormous clam here with its shell tightly closed.
-
-> s
-
-You're at complex junction.
-
-> west
-
-You're in Bedquilt.
-
-> west
-
-You're in Swiss Cheese Room.
-
-There is a little axe here.
-
-> west
-
-You're at east end of Twopit Room.
+Please answer the question.
 
-There is a huge beanstalk growing out of the west pit up to the hole.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
 > west
 
-You are at the west end of the Twopit Room.  There is a large hole in
-the wall above the pit at this end of the room.
+Please answer the question.
 
-There is a huge beanstalk growing out of the west pit up to the hole.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
 > d
 
-You are at the bottom of the western pit in the Twopit Room.  There is
-a large hole in the wall about 25 feet above you.
+Please answer the question.
 
-There is a gigantic beanstalk stretching all the way up to the hole.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
 > climb
 
-You clamber up the plant and scurry through the hole at the top.
+Please answer the question.
 
-You're in narrow corridor.
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
 > west
 
-You're in Giant Room.
+Please answer the question.
 
-There is a large nest here, full of golden eggs!
+Oh dear, you seem to have gotten yourself killed.  I might be able to
+help you out, but I've never really done this before.  Do you want me
+to try to reincarnate you?
 
 > n
 
-You are at one end of an immense north/south passage.
-
-There is an empty bottle here.
-
-The way north leads through a massive, rusty, iron door.
-
-> take bottl
-
 OK
 
-> n
-
-You're in cavern with waterfall.
-
-There is a jewel-encrusted trident here!
-
-> w
-
-You're at steep incline above large room.
-
-> d
-
-You're in large low room.
-
-> se
-
-You're in Oriental Room.
-
-There is a delicate, precious, ming vase here!
-
-> se
-
-You are in a room whose walls resemble Swiss cheese.  Obvious passages
-go west, east, ne, and nw.  Part of the room is occupied by a large
-bedrock block.
-
-There is a little axe here.
-
-> west
-
-You're at east end of Twopit Room.
-
-There is a huge beanstalk growing out of the west pit up to the hole.
-
-> d
-
-You're in east pit.
-
-> g oil
-
-Your bottle is now full of oil.
-
-> u
-
-You're at east end of Twopit Room.
-
-There is a huge beanstalk growing out of the west pit up to the hole.
-
-> west
-
-You're at west end of Twopit Room.
-
-There is a huge beanstalk growing out of the west pit up to the hole.
-
-> west
-
-You're in Slab Room.
-
-> u
-
-You are in a secret n/s canyon above a large room.
-
-> s
-
-You are in a secret canyon which exits to the north and east.
-
-The blood-specked body of a huge green dead dragon lies to one side.
-
-> e
-
-You're in secret e/w canyon above tight canyon.
-
-> e
-
-You're in Hall of Mt King.
-
-A cheerful little bird is sitting here singing.
-
-> n
-
-You're in n/s passage above e/w passage.
-
-There are bars of silver here!
-
-> n
-
-You're at "Y2".
-
-> plugh
-
->>Foof!<<
-
-You're inside building.
-
-There is a Persian rug spread out on the floor!
-
-> take
-
-OK
-
-> out
-
-You're in front of building.
-
-> west
-
-You have walked up a hill, still in the forest.  The road slopes back
-down the other side of the hill.  There is a building in the distance.
-
-> n
-
-You are wandering aimlessly through the forest.
-
-> n
-
-You are wandering aimlessly through the forest.
-
-> n
-
-The forest thins out here to reveal a steep cliff.  There is no way
-down, but a small ledge can be seen to the west across the chasm.
-
-A small urn is embedded in the rock.
-
-> fill urn
-
-Your bottle is now empty and the urn is full of oil.
-
-> light
-
-The urn is now lit.
-
-> rub urn
-
-As you rub the urn, there is a flash of light and a genie appears.
-His aspect is stern as he advises: "One who wouldst traffic in
-precious stones must first learn to recognize the signals thereof."
-He wrests the urn from the stone, leaving a small cavity.  Turning to
-face you again, he fixes you with a steely eye and intones: "Caution!"
-Genie and urn vanish in a cloud of amber smoke.  The smoke condenses
-to form a rare amber gemstone, resting in the cavity in the rock.
-
-> take amber
-
-OK
-
-> drop rug
-
-OK
-
-> drop emera
-
-The gem fits easily into the cavity.
-
-The Persian rug stiffens and rises a foot or so off the ground.
-
-> fly
-
-You board the Persian rug, which promptly whisks you across the chasm.
-You have time for a fleeting glimpse of a two thousand foot drop to a
-mighty river; then you find yourself on the other side.
-
-You are on a small ledge on one face of a sheer cliff.  There are no
-paths away from the ledge.  Across the chasm is a small clearing
-surrounded by forest.
-
-There is a Persian rug here, hovering in mid-air!
-
-A brilliant blue star sapphire is here!
-
-> e
-
-There is no way to go that direction.
-
-You're on ledge.
-
-There is a Persian rug here, hovering in mid-air!
-
-A brilliant blue star sapphire is here!
-
-
-You scored 81 out of a possible 430, using 237 turns.
+You scored 79 out of a possible 430, using 128 turns.
 
 Your score qualifies you as a novice class adventurer.
 
-To achieve the next higher rating, you need 40 more points.
+To achieve the next higher rating, you need 42 more points.
diff --git a/tests/reach_ledge_short.log b/tests/reach_ledge_short.log
index a121333..f53f98d 100644
--- a/tests/reach_ledge_short.log
+++ b/tests/reach_ledge_short.log
@@ -1,4 +1,6 @@
 ## LOC_NOCLIMB.short (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
@@ -83,7 +85,7 @@ kill machi
 s
 s
 kill ogre
- 
+z
 s
 west
 n
@@ -214,7 +216,7 @@ se
 se
 west
 d
-g oil
+get oil
 u
 west
 west
@@ -238,4 +240,4 @@ take amber
 drop rug
 drop emera
 fly
-e
\ No newline at end of file
+e
diff --git a/tests/reach_noclimb.chk b/tests/reach_noclimb.chk
index 0a06bd0..6f42d7c 100644
--- a/tests/reach_noclimb.chk
+++ b/tests/reach_noclimb.chk
@@ -170,7 +170,7 @@ You're in west pit.
 
 There is a tiny little plant in the pit, murmuring "water, water, ..."
 
-
+> 
 You scored 59 out of a possible 430, using 24 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/reach_noclimb.log b/tests/reach_noclimb.log
index 42af7c5..f3670e6 100644
--- a/tests/reach_noclimb.log
+++ b/tests/reach_noclimb.log
@@ -1,4 +1,6 @@
 ## LOC_NOCLIMB (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
@@ -24,4 +26,4 @@ w
 w
 w
 d
-climb
\ No newline at end of file
+climb
diff --git a/tests/reach_planttop.chk b/tests/reach_planttop.chk
index 8009e1f..c19c9d2 100644
--- a/tests/reach_planttop.chk
+++ b/tests/reach_planttop.chk
@@ -387,7 +387,7 @@ You're at west end of Twopit Room.
 
 The top of a 12-foot-tall beanstalk is poking out of the west pit.
 
-
+> 
 You scored 63 out of a possible 430, using 50 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/reach_planttop.log b/tests/reach_planttop.log
index bbdf94b..851c55a 100644
--- a/tests/reach_planttop.log
+++ b/tests/reach_planttop.log
@@ -1,4 +1,6 @@
 ## LOC_PLANTTOP (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
@@ -50,4 +52,4 @@ s
 s
 d
 water plant
-climb
\ No newline at end of file
+climb
diff --git a/tests/reincarnate.chk b/tests/reincarnate.chk
index c8a8842..edaaf8a 100644
--- a/tests/reincarnate.chk
+++ b/tests/reincarnate.chk
@@ -143,7 +143,7 @@ There is food here.
 
 There is a bottle of water here.
 
-
+> 
 You scored 47 out of a possible 430, using 18 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/reincarnate.log b/tests/reincarnate.log
index 39be5dd..550be2f 100644
--- a/tests/reincarnate.log
+++ b/tests/reincarnate.log
@@ -1,4 +1,6 @@
 ## Jump into a pit and die, then be reincarnated
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1495774850
 in
diff --git a/tests/resumefail.chk b/tests/resumefail.chk
index 7be9b12..976fcc9 100644
--- a/tests/resumefail.chk
+++ b/tests/resumefail.chk
@@ -24,9 +24,10 @@ Is this acceptable?
 OK
 Can't open file /badfilename, try again.
 
+File name: 
 You're in front of building.
 
-
+> 
 You scored 32 out of a possible 430, using 1 turn.
 
 You are obviously a rank amateur.  Better luck next time.
diff --git a/tests/resumefail.log b/tests/resumefail.log
index 053b05f..6ca8d49 100644
--- a/tests/resumefail.log
+++ b/tests/resumefail.log
@@ -1,6 +1,9 @@
 ## Resume from invalid filename
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE advent430 crashes on resume from invalid filename and we don't care.
 n
 seed 1240742801
 resume
 y
-/badfilename
\ No newline at end of file
+/badfilename
diff --git a/tests/resumefail2.chk b/tests/resumefail2.chk
index 756c094..7493ad8 100644
--- a/tests/resumefail2.chk
+++ b/tests/resumefail2.chk
@@ -11,12 +11,12 @@ down a gully.
 Can't open file y, try again.
 
 I'm sorry, but that Adventure was begun using Version -133.-7 of the
-save file format, and this program uses Version 2.9.  You must find an instance
+save file format, and this program uses Version 3.0.  You must find an instance
 using that other version in order to resume that Adventure.
 
 You're in front of building.
 
-
+> 
 You scored 32 out of a possible 430, using 1 turn.
 
 You are obviously a rank amateur.  Better luck next time.
diff --git a/tests/resumefail2.log b/tests/resumefail2.log
index 2754454..30b3e20 100644
--- a/tests/resumefail2.log
+++ b/tests/resumefail2.log
@@ -1,4 +1,7 @@
-## Resume from from generated save with  version mismatch error
+## Resume from generated save with version mismatch error
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE Reveals a bug in advent430 handling of saves with invalid versions.
 n
 resume
 y
diff --git a/tests/savefail.chk b/tests/savefail.chk
index de89a53..0f005a2 100644
--- a/tests/savefail.chk
+++ b/tests/savefail.chk
@@ -25,9 +25,10 @@ Is this acceptable?
 OK
 Can't open file /, try again.
 
+File name: 
 You're in front of building.
 
-
+> 
 You scored 27 out of a possible 430, using 1 turn.
 
 You are obviously a rank amateur.  Better luck next time.
diff --git a/tests/savefail.log b/tests/savefail.log
index f907d99..d5c5b6e 100644
--- a/tests/savefail.log
+++ b/tests/savefail.log
@@ -1,6 +1,9 @@
 ## Save right after starting to invalid filename
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE advent430 crashes on save to invalid filename and we don't care.
 n
 seed 1240742801
 save
 y
-/
\ No newline at end of file
+/
diff --git a/tests/saveresume.1.log b/tests/saveresume.1.log
index fffe43f..aa74e77 100644
--- a/tests/saveresume.1.log
+++ b/tests/saveresume.1.log
@@ -1,4 +1,7 @@
 ## Save right after starting
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE Can't compare to advent430 due to version skew
 n
 seed 1240742801
 save
diff --git a/tests/saveresume.2.log b/tests/saveresume.2.log
index 7ceb5dd..bda1a1e 100644
--- a/tests/saveresume.2.log
+++ b/tests/saveresume.2.log
@@ -1,4 +1,7 @@
 ## Resume and then quit
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE Can't compare to advent430 due to version skew
 n
 in
 resume
diff --git a/tests/saveresume.3.log b/tests/saveresume.3.log
index 13ed0be..7777da0 100644
--- a/tests/saveresume.3.log
+++ b/tests/saveresume.3.log
@@ -1,5 +1,8 @@
 ## Almost win, then save
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56
+#NOCOMPARE Seems to reveal a bug in advent430's save function.
 n
 seed 1838473132
 in
@@ -473,4 +476,4 @@ sw
 save
 y
 saveresume_win.adv
-y
\ No newline at end of file
+y
diff --git a/tests/saveresume.4.log b/tests/saveresume.4.log
index caa8098..1009ea7 100644
--- a/tests/saveresume.4.log
+++ b/tests/saveresume.4.log
@@ -1,6 +1,9 @@
 ## Resume, then win
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # Here to get class threshold of 426
 # Note, savefile name has trailing space
+#NOCOMPARE Reveals that advent430 does not resume in endgame gracefully.
 n
 resume
 y
diff --git a/tests/saveresumeopt.chk b/tests/saveresumeopt.chk
index bc08d9b..6e8ead0 100644
--- a/tests/saveresumeopt.chk
+++ b/tests/saveresumeopt.chk
@@ -1,7 +1,7 @@
 
 You're in front of building.
 
-
+> 
 You scored 27 out of a possible 430, using 2 turns.
 
 You are obviously a rank amateur.  Better luck next time.
diff --git a/tests/saveresumeopt.log b/tests/saveresumeopt.log
index af159ff..e52593d 100644
--- a/tests/saveresumeopt.log
+++ b/tests/saveresumeopt.log
@@ -1,2 +1,5 @@
 ## Simple quit
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE New feature, -r option
 #options: -r saveresume.adv
diff --git a/tests/savetamper.chk b/tests/savetamper.chk
new file mode 100644
index 0000000..88f86f7
--- /dev/null
+++ b/tests/savetamper.chk
@@ -0,0 +1,17 @@
+
+Welcome to Adventure!!  Would you like instructions?
+
+> n
+
+You are standing at the end of a road before a small brick building.
+Around you is a forest.  A small stream flows out of the building and
+down a gully.
+
+> resume
+
+A dark fog creeps in to surround you.  From somewhere in the fog you
+hear a stern voice.  "This Adventure has been tampered with!  You have
+been dabbling in magic, knowing not the havoc you might cause thereby.
+Leave at once, before you do irrevocable harm!"  The fog thickens,
+until at last you can see nothing at all.  Your vision then clears,
+and you find yourself back in The Real World.
diff --git a/tests/savetamper.log b/tests/savetamper.log
new file mode 100644
index 0000000..6662443
--- /dev/null
+++ b/tests/savetamper.log
@@ -0,0 +1,7 @@
+## Resume from artificial "corrupted" save
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE Can't compare to advent430 due to version skew
+n
+resume
+cheat_savetamper.adv
diff --git a/tests/seedcrash.log b/tests/seedcrash.log
deleted file mode 100644
index 7f364cc..0000000
--- a/tests/seedcrash.log
+++ /dev/null
@@ -1,225 +0,0 @@
-## This crashed advent before the control path after seed was fixed.
-n
-seed 1635997320
-in
-take lamp
-xyzzy
-take rod
-e
-take cage
-w
-on
-w
-w
-drop rod
-take bird
-take rod
-w
-free bird
-wave rod
-drop rod
-take bird
-take jade
-e
-e
-e
-off
-xyzzy
-drop jade
-xyzzy
-on
-w
-w
-w
-take rod
-d
-w
-wave rod
-drop rod
-e
-n
-free bird
-take bird
-s
-take jewelry
-n
-sw
-w
-feed dragon
-kill dragon
-yes
-drink blood
-take rug
-e
-e
-n
-take silver
-n
-off
-plugh
-drop jewelry
-drop rug
-drop silver
-out
-s
-w
-n
-take appendage
-free bird
-drop cage
-listen
-s
-s
-n
-in
-take water
-plugh
-on
-plover
-ne
-take pyramid
-s
-plover
-s
-d
-take axe
-u
-s
-up
-w
-w
-w
-w
-throw axe
-take axe
-w
-s
-sw
-se
-s
-kill machine
-s
-s
-kill ogre
-n
-take ruby
-s
-w
-n
-n
-n
-nw
-d
-e
-e
-e
-take diamonds
-e
-e
-drop bottle
-s
-take gold
-n
-n
-n
-n
-off
-plugh
-drop gold
-drop diamonds
-drop pyramid
-drop ruby
-plugh
-on
-s
-s
-u
-take water
-throw axe
-take axe
-n
-n
-d
-bedquilt
-slab
-s
-d
-water plant
-u
-w
-u
-reservoir
-F'UNJ
-n
-n
-nw
-u
-u
-u
-u
-ne
-take ebony
-sw
-d
-d
-d
-d
-d
-take water
-s
-s
-s
-s
-d
-s
-d
-water plant
-u
-e
-d
-get oil
-u
-w
-d
-climb
-w
-n
-oil door
-drop bottle
-drop appendage
-n
-take trident
-w
-d
-se
-n
-w
-inven
-drop trident
-drop ebony
-drop axe
-drop lantern
-e
-take emerald
-w
-take lamp
-take axe
-take ebony
-take trident
-nw
-s
-take vase
-se
-e
-take pillow
-w
-ne
-e
-n
-n
-seed 1635997320
-n
-
-
-
-
diff --git a/tests/snake_food.chk b/tests/snake_food.chk
index 96f6900..56e73b3 100644
--- a/tests/snake_food.chk
+++ b/tests/snake_food.chk
@@ -151,7 +151,7 @@ Set of keys
 Brass lantern
 Wicker cage
 
-
+> 
 You scored 57 out of a possible 430, using 22 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/snake_food.log b/tests/snake_food.log
index 4950277..843fa0e 100644
--- a/tests/snake_food.log
+++ b/tests/snake_food.log
@@ -1,4 +1,6 @@
 ## Snake must vocally eat bird
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1951269982
 in
diff --git a/tests/softroom.chk b/tests/softroom.chk
index cc168f3..3e9c86d 100644
--- a/tests/softroom.chk
+++ b/tests/softroom.chk
@@ -1350,7 +1350,7 @@ There is a delicate, precious, ming vase here!
 
 > 
 
-
+> 
 You scored 191 out of a possible 430, using 223 turns.
 
 You may now consider yourself a "Seasoned Adventurer".
diff --git a/tests/softroom.log b/tests/softroom.log
index b6b60e7..9bb6185 100644
--- a/tests/softroom.log
+++ b/tests/softroom.log
@@ -1,4 +1,6 @@
 ## Drop vase in soft room after pillow removed
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # Verify that the vase does not break
 n
 seed 1838473132
diff --git a/tests/specials.chk b/tests/specials.chk
index 1b207d0..0606117 100644
--- a/tests/specials.chk
+++ b/tests/specials.chk
@@ -73,7 +73,7 @@ I'm as confused as you are.
 
 Mist is a white vapor, usually water, seen from time to time in
 caverns.  It can be found anywhere but is frequently a sign of a deep
-pit leading down to water.'
+pit leading down to water.
 
 > fuck
 
@@ -131,7 +131,7 @@ can now save a game and resume it at once (formerly you had to wait a
 while first), but it now costs you a few points each time you save the
 game.  Saved games are now stored in much smaller files than before.
 
-
+> 
 You scored 32 out of a possible 430, using 15 turns.
 
 You are obviously a rank amateur.  Better luck next time.
diff --git a/tests/specials.log b/tests/specials.log
index 2891691..7900a6c 100644
--- a/tests/specials.log
+++ b/tests/specials.log
@@ -1,4 +1,7 @@
 ## Test special words
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE The news text has changed
 n
 thank
 shazam
diff --git a/tests/splatter.log b/tests/splatter.log
index 2408bcd..76df98e 100644
--- a/tests/splatter.log
+++ b/tests/splatter.log
@@ -1,4 +1,6 @@
 ## Adventurer fall down go boom. Also tests 'say' verb on magic words.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56
 n
 seed 1838473132
diff --git a/tests/seedcrash.chk b/tests/stashed.chk
similarity index 52%
rename from tests/seedcrash.chk
rename to tests/stashed.chk
index 1f10129..58b989c 100644
--- a/tests/seedcrash.chk
+++ b/tests/stashed.chk
@@ -1,19 +1,19 @@
 
 Welcome to Adventure!!  Would you like instructions?
 
-> n
+> no
 
 You are standing at the end of a road before a small brick building.
 Around you is a forest.  A small stream flows out of the building and
 down a gully.
 
-> seed 1635997320
+> seed 1318612053
 
-Seed set to 1635997320
+Seed set to 1318612053
 
 You're in front of building.
 
-> in
+> e
 
 You are inside a building, a well house for a large spring.
 
@@ -25,28 +25,22 @@ There is food here.
 
 There is a bottle of water here.
 
-> take lamp
-
-OK
-
-> xyzzy
+> plugh
 
 >>Foof!<<
 
 It is now pitch dark.  If you proceed you will likely fall into a pit.
 
-> take rod
-
-OK
+> plove
 
-> e
+>>Foof!<<
 
-You are crawling over cobbles in a low passage.  There is a dim light
-at the east end of the passage.
+You're in a small chamber lit by an eerie green light.  An extremely
+narrow tunnel exits to the west.  A dark corridor leads ne.
 
-There is a small wicker cage discarded nearby.
+There is an emerald here the size of a plover's egg!
 
-> take cage
+> get emerald
 
 OK
 
@@ -54,266 +48,248 @@ OK
 
 It is now pitch dark.  If you proceed you will likely fall into a pit.
 
-> on
-
-Your lamp is now on.
-
-You are in a debris room filled with stuff washed in from the surface.
-A low wide passage with cobbles becomes plugged with mud and debris
-here, but an awkward canyon leads upward and west.  In the mud someone
-has scrawled, "MAGIC WORD XYZZY".
+> drop emerald
 
-> w
+OK
 
-You are in an awkward sloping east/west canyon.
+> e
 
-> w
+You're in Plover Room.
 
-You are in a splendid chamber thirty feet high.  The walls are frozen
-rivers of orange stone.  An awkward canyon and a good passage exit
-from east and west sides of the chamber.
+> ne
 
-A cheerful little bird is sitting here singing.
+It is now pitch dark.  If you proceed you will likely fall into a pit.
 
-> drop rod
+> get pyramid
 
 OK
 
-> take bird
-
-OK
+> s
 
-> take rod
+You're in Plover Room.
 
-OK
+> plove
 
-> w
+>>Foof!<<
 
-At your feet is a small pit breathing traces of white mist.  An east
-passage ends here except for a small crack leading on.
+It is now pitch dark.  If you proceed you will likely fall into a pit.
 
-Rough stone steps lead down the pit.
+> plugh
 
-> free bird
+>>Foof!<<
 
-OK
+You're inside building.
 
-> wave rod
+There are some keys on the ground here.
 
-The bird flies about agitatedly for a moment, then disappears through
-the crack.  It reappears shortly, carrying in its beak a jade
-necklace, which it drops at your feet.
+There is a shiny brass lamp nearby.
 
-> drop rod
+There is food here.
 
-OK
+There is a bottle of water here.
 
-> take bird
+> drop pyramid
 
 OK
 
-> take jade
+> get lamp
 
 OK
 
-> e
-
-You're in bird chamber.
-
-> e
-
-You are in an awkward sloping east/west canyon.
-
-> e
+> get water
 
-You're in debris room.
+OK
 
-> off
+> plugh
 
-Your lamp is now off.
+>>Foof!<<
 
 It is now pitch dark.  If you proceed you will likely fall into a pit.
 
-> xyzzy
+> on
 
->>Foof!<<
+Your lamp is now on.
 
-You're inside building.
+You are in a large room, with a passage to the south, a passage to the
+west, and a wall of broken rock to the east.  There is a large "Y2" on
+a rock in the room's center.
 
-There are some keys on the ground here.
+A hollow voice says "PLUGH".
 
-There is food here.
+> s
 
-There is a bottle of water here.
+You are in a low n/s passage at a hole in the floor.  The hole goes
+down to an e/w passage.
 
-> drop jade
+There are bars of silver here!
 
-OK
+> d
 
-> xyzzy
+You are in a dirty broken passage.  To the east is a crawl.  To the
+west is a large passage.  Above you is a hole to another passage.
 
->>Foof!<<
+> bedquilt
 
-It is now pitch dark.  If you proceed you will likely fall into a pit.
+You are in Bedquilt, a long east/west passage with holes everywhere.
+To explore at random select north, south, up, or down.
 
-> on
+> w
 
-Your lamp is now on.
+You are in a room whose walls resemble Swiss cheese.  Obvious passages
+go west, east, ne, and nw.  Part of the room is occupied by a large
+bedrock block.
 
-You're in debris room.
+> e
 
-> w
+You are in the Soft Room.  The walls are covered with heavy curtains,
+the floor with a thick pile carpet.  Moss covers the ceiling.
 
-You are in an awkward sloping east/west canyon.
+A small velvet pillow lies on the floor.
 
-> w
+> take pillow
 
-You're in bird chamber.
+OK
 
 > w
 
-You're at top of small pit.
+You're in Swiss Cheese Room.
 
-A three foot black rod with a rusty star on an end lies nearby.
+> oriental
 
-Rough stone steps lead down the pit.
+This is the Oriental Room.  Ancient oriental cave drawings cover the
+walls.  A gently sloping passage leads upward to the north, another
+passage leads se, and a hands and knees crawl leads west.
 
-> take rod
+There is a delicate, precious, ming vase here!
 
-OK
+> take vase
 
-> d
+OK
 
-You are at one end of a vast hall stretching forward out of sight to
-the west.  There are openings to either side.  Nearby, a wide stone
-staircase leads downward.  The hall is filled with wisps of white mist
-swaying to and fro almost as if alive.  A cold wind blows up the
-staircase.  There is a passage at the top of a dome behind you.
+> n
 
-Rough stone steps lead up the dome.
+You are following a wide path around the outer edge of a large cavern.
+Far below, through a heavy white mist, strange splashing noises can be
+heard.  The mist rises up through a fissure in the ceiling.  The path
+exits to the south and west.
 
 > w
 
-You are on the east bank of a fissure slicing clear across the hall.
-The mist is quite thick here, and the fissure is too wide to jump.
-
-> wave rod
-
-The bird flies agitatedly about the cage.
+You are in an alcove.  A small nw path seems to widen after a short
+distance.  An extremely tight tunnel leads east.  It looks like a very
+tight squeeze.  An eerie light can be seen at the other end.
 
-A crystal bridge now spans the fissure.
+There is an emerald here the size of a plover's egg!
 
-> drop rod
+> take emerald
 
 OK
 
-> e
+> nw
 
-You're in Hall of Mists.
+You're in misty cavern.
 
-Rough stone steps lead up the dome.
+> s
 
-> n
+You're in Oriental Room.
 
-You are in the Hall of the Mountain King, with passages off in all
-directions.
+> se
 
-A huge green fierce snake bars the way!
+You're in Swiss Cheese Room.
 
-> free bird
+> w
 
-The little bird attacks the green snake, and in an astounding flurry
-drives the snake away.
+You are at the east end of the Twopit Room.  The floor here is
+littered with thin rock slabs, which make it easy to descend the pits.
+There is a path here bypassing the pits to connect passages from east
+and west.  There are holes all over, but the only big one is on the
+wall directly over the west pit where you can't get to it.
 
-> take bird
+> w
 
-OK
+You are at the west end of the Twopit Room.  There is a large hole in
+the wall above the pit at this end of the room.
 
-> s
+> d
 
-You are in the south side chamber.
+You are at the bottom of the western pit in the Twopit Room.  There is
+a large hole in the wall about 25 feet above you.
 
-There is precious jewelry here!
+There is a tiny little plant in the pit, murmuring "water, water, ..."
 
-> take jewelry
+> water plant
 
-OK
+The plant spurts into furious growth for a few seconds.
 
-> n
+You're in west pit.
 
-You're in Hall of Mt King.
+There is a 12-foot-tall beanstalk stretching up out of the pit,
+bellowing "WATER!! WATER!!"
 
-> sw
+> u
 
-You are in a secret canyon which here runs e/w.  It crosses over a
-very tight canyon 15 feet below.  If you go down you may not be able
-to get back up.
+You're at west end of Twopit Room.
 
-> w
+The top of a 12-foot-tall beanstalk is poking out of the west pit.
 
-You are in a secret canyon which exits to the north and east.
+> e
 
-A huge green fierce dragon bars the way!
+You're at east end of Twopit Room.
 
-The dragon is sprawled out on a Persian rug!!
+The top of a 12-foot-tall beanstalk is poking out of the west pit.
 
-> feed dragon
+> d
 
-There's nothing here it wants to eat (except perhaps you).
+You are at the bottom of the eastern pit in the Twopit Room.  There is
+a small pool of oil in one corner of the pit.
 
-> kill dragon
+> fill bottle
 
-With what?  Your bare hands?
+Your bottle is now full of oil.
 
-> yes
+> u
 
-Congratulations!  You have just vanquished a dragon with your bare
-hands!  (Unbelievable, isn't it?)
+You're at east end of Twopit Room.
 
-You are in a secret canyon which exits to the north and east.
+The top of a 12-foot-tall beanstalk is poking out of the west pit.
 
-There is a Persian rug spread out on the floor!
+> e
 
-The blood-specked body of a huge green dead dragon lies to one side.
+You're in Swiss Cheese Room.
 
-> drink blood
+> ne
 
-Your head buzzes strangely for a moment.
+You're in Bedquilt.
 
-> take rug
+> e
 
-OK
+You are at a complex junction.  A low hands and knees passage from the
+north joins a higher crawl from the east to make a walking passage
+going west.  There is also a large room above.  The air is damp here.
 
-> e
+> u
 
-You're in secret e/w canyon above tight canyon.
+You are in a large room full of dusty rocks.  There is a big hole in
+the floor.  There are cracks everywhere, and a passage leading east.
 
 > e
 
-You're in Hall of Mt King.
+You're in dirty passage.
 
-> n
+> u
 
-You are in a low n/s passage at a hole in the floor.  The hole goes
-down to an e/w passage.
+You're in n/s passage above e/w passage.
 
 There are bars of silver here!
 
-> take silver
+> n
 
-OK
-
-> n
-
-You are in a large room, with a passage to the south, a passage to the
-west, and a wall of broken rock to the east.  There is a large "Y2" on
-a rock in the room's center.
-
-> off
+A little dwarf just walked around a corner, saw you, threw a little
+axe at you which missed, cursed, and ran away.
 
-Your lamp is now off.
+You're at "Y2".
 
-It is now pitch dark.  If you proceed you will likely fall into a pit.
+There is a little axe here.
 
 > plugh
 
@@ -321,279 +297,349 @@ It is now pitch dark.  If you proceed you will likely fall into a pit.
 
 You're inside building.
 
-A precious jade necklace has been dropped here!
+There is a platinum pyramid here, 8 inches on a side!
 
 There are some keys on the ground here.
 
 There is food here.
 
-There is a bottle of water here.
-
-> drop jewelry
+> drop pillow
 
 OK
 
-> drop rug
+> drop vase
+
+The vase is now resting, delicately, on a velvet pillow.
+
+> drop bottle
 
 OK
 
-> drop silver
+> drop emerald
 
 OK
 
-> out
+> xyzzy
 
-You're in front of building.
+>>Foof!<<
 
-> s
+You are in a debris room filled with stuff washed in from the surface.
+A low wide passage with cobbles becomes plugged with mud and debris
+here, but an awkward canyon leads upward and west.  In the mud someone
+has scrawled, "MAGIC WORD XYZZY".
 
-You are in a valley in the forest beside a stream tumbling along a
-rocky bed.
+A three foot black rod with a rusty star on an end lies nearby.
 
-> w
+> take rod
 
-You are wandering aimlessly through the forest.
+OK
 
-> n
+> e
 
-You are wandering aimlessly through the forest.
+You are crawling over cobbles in a low passage.  There is a dim light
+at the east end of the passage.
 
-Your keen eye spots a severed leporine appendage lying on the ground.
+There is a small wicker cage discarded nearby.
 
-> take appendage
+> take cage
 
 OK
 
-> free bird
+> pit
 
-OK
+At your feet is a small pit breathing traces of white mist.  An east
+passage ends here except for a small crack leading on.
 
-> drop cage
+Rough stone steps lead down the pit.
+
+> drop rod
 
 OK
 
-> listen
+> e
 
-The bird is singing to you in gratitude for your having returned it to
-its home.  In return, it informs you of a magic word which it thinks
-you may find useful somewhere near the Hall of Mists.  The magic word
-changes frequently, but for now the bird believes it is "F'UNJ".  You
-thank the bird for this information, and it flies off into the forest.
+You are in a splendid chamber thirty feet high.  The walls are frozen
+rivers of orange stone.  An awkward canyon and a good passage exit
+from east and west sides of the chamber.
 
-> s
+A cheerful little bird is sitting here singing.
 
-You are wandering aimlessly through the forest.
+> take bird
 
-> s
+OK
 
-You're in valley.
+> w
 
-> n
+You're at top of small pit.
 
-You're in front of building.
+A three foot black rod with a rusty star on an end lies nearby.
 
-> in
+Rough stone steps lead down the pit.
 
-You're inside building.
+> drop bird
 
-There are bars of silver here!
+OK
 
-There is a Persian rug spread out on the floor!
+> take rod
 
-There is precious jewelry here!
+OK
 
-A precious jade necklace has been dropped here!
+> wave rod
 
-There are some keys on the ground here.
+The bird flies about agitatedly for a moment, then disappears through
+the crack.  It reappears shortly, carrying in its beak a jade
+necklace, which it drops at your feet.
 
-There is food here.
+> take necklace
 
-There is a bottle of water here.
+OK
 
-> take water
+> drop rod
 
 OK
 
-> plugh
+> take bird
 
->>Foof!<<
+OK
 
-It is now pitch dark.  If you proceed you will likely fall into a pit.
+> d
 
-> on
+You are at one end of a vast hall stretching forward out of sight to
+the west.  There are openings to either side.  Nearby, a wide stone
+staircase leads downward.  The hall is filled with wisps of white mist
+swaying to and fro almost as if alive.  A cold wind blows up the
+staircase.  There is a passage at the top of a dome behind you.
 
-Your lamp is now on.
+Rough stone steps lead up the dome.
 
-You're at "Y2".
+> s
 
-> plover
+This is a low room with a crude note on the wall.  The note says,
+"You won't get it up the steps".
 
->>Foof!<<
+There is a large sparkling nugget of gold here!
 
-You're in a small chamber lit by an eerie green light.  An extremely
-narrow tunnel exits to the west.  A dark corridor leads ne.
+> take nugget
 
-There is an emerald here the size of a plover's egg!
+OK
 
-> ne
+> n
 
-You're in the dark-room.  A corridor leading south is the only exit.
+You're in Hall of Mists.
 
-A massive stone tablet embedded in the wall reads:
-"Congratulations on bringing light into the dark-room!"
+> n
 
-There is a platinum pyramid here, 8 inches on a side!
+You are in the Hall of the Mountain King, with passages off in all
+directions.
 
-> take pyramid
+A huge green fierce snake bars the way!
 
-OK
+> drop bird
 
-> s
+The little bird attacks the green snake, and in an astounding flurry
+drives the snake away.
 
-You're in Plover Room.
+> take bird
 
-There is an emerald here the size of a plover's egg!
+OK
 
-> plover
+> sw
 
->>Foof!<<
+You are in a secret canyon which here runs e/w.  It crosses over a
+very tight canyon 15 feet below.  If you go down you may not be able
+to get back up.
 
-You're at "Y2".
+> w
 
-A hollow voice says "PLUGH".
+You are in a secret canyon which exits to the north and east.
 
-> s
+A huge green fierce dragon bars the way!
 
-You're in n/s passage above e/w passage.
+The dragon is sprawled out on a Persian rug!!
 
-> d
+> kill dragon
 
-A little dwarf just walked around a corner, saw you, threw a little
-axe at you which missed, cursed, and ran away.
+With what?  Your bare hands?
 
-You are in a dirty broken passage.  To the east is a crawl.  To the
-west is a large passage.  Above you is a hole to another passage.
+> yes
 
-There is a little axe here.
+Congratulations!  You have just vanquished a dragon with your bare
+hands!  (Unbelievable, isn't it?)
 
-> take axe
+You are in a secret canyon which exits to the north and east.
 
-OK
+There is a Persian rug spread out on the floor!
 
-> u
+The blood-specked body of a huge green dead dragon lies to one side.
 
-There is a threatening little dwarf in the room with you!
+> drink blood
 
-You're in n/s passage above e/w passage.
+Your head buzzes strangely for a moment.
 
-> s
+> take rug
 
-There is a threatening little dwarf in the room with you!
+OK
 
-You're in Hall of Mt King.
+> e
 
-> up
+You're in secret e/w canyon above tight canyon.
 
-There is a threatening little dwarf in the room with you!
+> e
 
-You're in Hall of Mists.
+You're in Hall of Mt King.
 
-Rough stone steps lead up the dome.
+> n
 
-> w
+You're in n/s passage above e/w passage.
 
-There is a threatening little dwarf in the room with you!
+There are bars of silver here!
 
-You're on east bank of fissure.
+> take bars
 
-A three foot black rod with a rusty star on an end lies nearby.
+OK
 
-A crystal bridge spans the fissure.
+> n
 
-> w
+You're at "Y2".
 
-There is a threatening little dwarf in the room with you!
+There is a little axe here.
 
-You are on the west side of the fissure in the Hall of Mists.
+> plugh
 
-There are diamonds here!
+>>Foof!<<
 
-A crystal bridge spans the fissure.
+You're inside building.
 
-> w
+There is an emerald here the size of a plover's egg!
 
-There is a threatening little dwarf in the room with you!
+There is a bottle of oil here.
 
-You are at the west end of the Hall of Mists.  A low wide crawl
-continues west and another goes north.  To the south is a little
-passage 6 feet off the floor.
+There is a delicate, precious, ming vase here!
 
-> w
+A small velvet pillow lies on the floor.
 
-There are 2 threatening little dwarves in the room with you.
+There is a platinum pyramid here, 8 inches on a side!
 
-One sharp nasty knife is thrown at you!
+There are some keys on the ground here.
 
-It misses!
+There is food here.
 
-You are at the east end of a very long hall apparently without side
-chambers.  To the east a low wide crawl slants up.  To the north a
-round two foot hole slants down.
+> drop cage
 
-> throw axe
+OK
 
-You killed a little dwarf.  The body vanishes in a cloud of greasy
-black smoke.
+> drop necklace
 
-There is a threatening little dwarf in the room with you!
+OK
 
-One sharp nasty knife is thrown at you!
+> drop nugget
 
-It misses!
+OK
 
-You're at east end of long hall.
+> drop bars
 
-There is a little axe here.
+OK
 
-> take axe
+> drop rug
 
 OK
 
-> w
+> xyzzy
 
-There is a threatening little dwarf in the room with you!
+>>Foof!<<
 
-You are at the west end of a very long featureless hall.  The hall
-joins up with a narrow north/south passage.
+You're in debris room.
 
-> s
+> pit
 
-There is a threatening little dwarf in the room with you!
+You're at top of small pit.
 
-You are in a maze of twisty little passages, all different.
+A three foot black rod with a rusty star on an end lies nearby.
 
-> sw
+Rough stone steps lead down the pit.
 
-There is a threatening little dwarf in the room with you!
+> take rod
 
-You are in a little maze of twisty passages, all different.
+OK
 
-> se
+> d
 
-There is a threatening little dwarf in the room with you!
+You're in Hall of Mists.
 
-You are in a little maze of twisting passages, all different.
+Rough stone steps lead up the dome.
 
-> s
+> w
 
-There is a threatening little dwarf in the room with you!
+You are on the east bank of a fissure slicing clear across the hall.
+The mist is quite thick here, and the fissure is too wide to jump.
 
-Dead end
+> wave rod
 
-There is a massive and somewhat battered vending machine here.  The
-instructions on it read: "Drop coins here to receive fresh batteries."
+A crystal bridge now spans the fissure.
+
+> w
+
+You are on the west side of the fissure in the Hall of Mists.
+
+There are diamonds here!
+
+A crystal bridge spans the fissure.
+
+> take diamonds
+
+OK
+
+> w
+
+There is a threatening little dwarf in the room with you!
+
+You are at the west end of the Hall of Mists.  A low wide crawl
+continues west and another goes north.  To the south is a little
+passage 6 feet off the floor.
+
+> w
+
+There is a threatening little dwarf in the room with you!
+
+You are at the east end of a very long hall apparently without side
+chambers.  To the east a low wide crawl slants up.  To the north a
+round two foot hole slants down.
+
+> w
+
+There is a threatening little dwarf in the room with you!
+
+You are at the west end of a very long featureless hall.  The hall
+joins up with a narrow north/south passage.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+You are in a maze of twisty little passages, all different.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+You are in a maze of twisting little passages, all different.
+
+> e
+
+There is a threatening little dwarf in the room with you!
+
+You are in a little maze of twisting passages, all different.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+Dead end
+
+There is a massive and somewhat battered vending machine here.  The
+instructions on it read: "Drop coins here to receive fresh batteries."
 
-> kill machine
+> hit machine
 
 As you strike the vending machine, it pivots backward along with a
 section of wall, revealing a dark passage leading south.
@@ -623,107 +669,817 @@ The ogre, distracted by your rush, is struck by the knife.  With a
 blood-curdling yell he turns and bounds after the dwarf, who flees
 in panic.  You are left alone in the room.
 
-> n
+> n
+
+You are in the ogre's storeroom.  The only exit is to the south.
+
+There is an enormous ruby here!
+
+> take ruby
+
+OK
+
+> s
+
+You are in a large chamber with passages to the west and north.
+
+> w
+
+You are in a long, rough-hewn, north/south corridor.
+
+> n
+
+Dead end
+
+There is a massive vending machine here, swung back to reveal a
+southward passage.
+
+> n
+
+You are in a little maze of twisting passages, all different.
+
+> sw
+
+You are in a maze of twisting little passages, all different.
+
+> w
+
+You are in a maze of twisty little passages, all different.
+
+> d
+
+You're at west end of long hall.
+
+> n
+
+You are at a crossover of a high n/s passage and a low e/w one.
+
+> e
+
+You are in the west side chamber of the Hall of the Mountain King.
+A passage continues west and up here.
+
+There are many coins here!
+
+> take coins
+
+OK
+
+> e
+
+You're in Hall of Mt King.
+
+> s
+
+You are in the south side chamber.
+
+There is precious jewelry here!
+
+> take jewelry
+
+OK
+
+> n
+
+You're in Hall of Mt King.
+
+> e
+
+You're in Hall of Mists.
+
+Rough stone steps lead up the dome.
+
+> w
+
+You're on east bank of fissure.
+
+A crystal bridge spans the fissure.
+
+> w
+
+You're on west bank of fissure.
+
+A crystal bridge spans the fissure.
+
+> w
+
+You're at west end of Hall of Mists.
+
+> s
+
+You are in a maze of twisty little passages, all alike.
+
+> e
+
+Out from the shadows behind you pounces a bearded pirate!  "Har, har,"
+he chortles, "I'll just take all this booty and hide it away with me
+chest deep in the maze!"  He snatches your treasure and vanishes into
+the gloom.
+
+You are in a maze of twisty little passages, all alike.
+
+> s
+
+You are in a maze of twisty little passages, all alike.
+
+> s
+
+You are in a maze of twisty little passages, all alike.
+
+> s
+
+You are in a maze of twisty little passages, all alike.
+
+> n
+
+You are in a maze of twisty little passages, all alike.
+
+> e
+
+You are on the brink of a thirty foot pit with a massive orange column
+down one wall.  You could climb down here but you could not get back
+up.  The maze continues at this level.
+
+> e
+
+You are in a maze of twisty little passages, all alike.
+
+> nw
+
+Dead end
+
+There is an enormous ruby here!
+
+There are many coins here!
+
+There is precious jewelry here!
+
+There are diamonds here!
+
+The pirate's treasure chest is here!
+
+> drop rod
+
+OK
+
+> take jewelry
+
+OK
+
+> take chest
+
+OK
+
+> take ruby
+
+OK
+
+> take diamonds
+
+OK
+
+> take coins
+
+OK
+
+> se
+
+There is a threatening little dwarf in the room with you!
+
+You are in a maze of twisty little passages, all alike.
+
+> w
+
+There is a threatening little dwarf in the room with you!
+
+You are in a maze of twisty little passages, all alike.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+You're at brink of pit.
+
+> d
+
+You're in bird chamber.
+
+> debris
+
+You're in debris room.
+
+> xyzzy
+
+>>Foof!<<
+
+You're inside building.
+
+There is a Persian rug spread out on the floor!
+
+There are bars of silver here!
+
+There is a large sparkling nugget of gold here!
+
+A precious jade necklace has been dropped here!
+
+There is a small wicker cage discarded nearby.
+
+There is a little bird in the cage.
+
+There is an emerald here the size of a plover's egg!
+
+There is a bottle of oil here.
+
+There is a delicate, precious, ming vase here!
+
+A small velvet pillow lies on the floor.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+There are some keys on the ground here.
+
+There is food here.
+
+> off
+
+Your lamp is now off.
+
+> drop coins
+
+OK
+
+> drop diamonds
+
+OK
+
+> drop jewelry
+
+OK
+
+> drop chest
+
+OK
+
+> drop lamp
+
+OK
+
+> take rug
+
+OK
+
+> take emerald
+
+OK
+
+> take cage
+
+OK
+
+> take bottle
+
+OK
+
+> w
+
+You're in front of building.
+
+> s
+
+You are in a valley in the forest beside a stream tumbling along a
+rocky bed.
+
+> w
+
+You are wandering aimlessly through the forest.
+
+> drop bird
+
+OK
+
+> listen
+
+The bird is singing to you in gratitude for your having returned it to
+its home.  In return, it informs you of a magic word which it thinks
+you may find useful somewhere near the Hall of Mists.  The magic word
+changes frequently, but for now the bird believes it is "N'BEH".  You
+thank the bird for this information, and it flies off into the forest.
+
+> drop cage
+
+OK
+
+> n
+
+You are wandering aimlessly through the forest.
+
+Your keen eye spots a severed leporine appendage lying on the ground.
+
+> take appendage
+
+OK
+
+> n
+
+You are wandering aimlessly through the forest.
+
+> e
+
+You are wandering aimlessly through the forest.
+
+> n
+
+You are wandering aimlessly through the forest.
+
+> n
+
+The forest thins out here to reveal a steep cliff.  There is no way
+down, but a small ledge can be seen to the west across the chasm.
+
+A small urn is embedded in the rock.
+
+> fill urn
+
+Your bottle is now empty and the urn is full of oil.
+
+> light urn
+
+The urn is now lit.
+
+> rub urn
+
+As you rub the urn, there is a flash of light and a genie appears.
+His aspect is stern as he advises: "One who wouldst traffic in
+precious stones must first learn to recognize the signals thereof."
+He wrests the urn from the stone, leaving a small cavity.  Turning to
+face you again, he fixes you with a steely eye and intones: "Caution!"
+Genie and urn vanish in a cloud of amber smoke.  The smoke condenses
+to form a rare amber gemstone, resting in the cavity in the rock.
+
+> drop rug
+
+OK
+
+> take amber
+
+OK
+
+> drop emerald
+
+The gem fits easily into the cavity.
+
+The Persian rug stiffens and rises a foot or so off the ground.
+
+> fly
+
+You board the Persian rug, which promptly whisks you across the chasm.
+You have time for a fleeting glimpse of a two thousand foot drop to a
+mighty river; then you find yourself on the other side.
+
+You are on a small ledge on one face of a sheer cliff.  There are no
+paths away from the ledge.  Across the chasm is a small clearing
+surrounded by forest.
+
+There is a Persian rug here, hovering in mid-air!
+
+A brilliant blue star sapphire is here!
+
+> take sapphire
+
+OK
+
+> fly
+
+The rug ferries you back across the chasm.
+
+You're at cliff.
+
+There is an emerald resting in a small cavity in the rock!
+
+There is a Persian rug here, hovering in mid-air!
+
+> take emerald
+
+OK
+
+> drop ruby
+
+The gem fits easily into the cavity.
+
+The Persian rug settles gently to the ground.
+
+> take rug
+
+OK
+
+> take ruby
+
+OK
+
+> e
+
+You are wandering aimlessly through the forest.
+
+> s
+
+You are wandering aimlessly through the forest.
+
+> e
+
+You have walked up a hill, still in the forest.  The road slopes back
+down the other side of the hill.  There is a building in the distance.
+
+> e
+
+You're in front of building.
+
+> e
+
+You are inside a building, a well house for a large spring.
+
+There is a shiny brass lamp nearby.
+
+The pirate's treasure chest is here!
+
+There is precious jewelry here!
+
+There are diamonds here!
+
+There are many coins here!
+
+There are bars of silver here!
+
+There is a large sparkling nugget of gold here!
+
+A precious jade necklace has been dropped here!
+
+There is a delicate, precious, ming vase here!
+
+A small velvet pillow lies on the floor.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+There are some keys on the ground here.
+
+There is food here.
+
+> drop emerald
+
+OK
+
+> drop ruby
+
+OK
+
+> drop amber
+
+OK
+
+> drop rug
+
+OK
+
+> drop sapphire
+
+OK
+
+> fill bottle
+
+Your bottle is now full of water.
+
+> take lamp
+
+OK
+
+> plugh
+
+>>Foof!<<
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> on
+
+Your lamp is now on.
+
+You're at "Y2".
+
+There is a little axe here.
+
+> s
+
+You're in n/s passage above e/w passage.
+
+> s
+
+You're in Hall of Mt King.
+
+> sw
+
+You're in secret e/w canyon above tight canyon.
+
+> w
+
+You are in a secret canyon which exits to the north and east.
+
+The body of a huge green dead dragon is lying off to one side.
+
+> n
+
+You are in a secret n/s canyon above a large room.
+
+> reservoir
+
+You are at the edge of a large underground reservoir.  An opaque cloud
+of white mist fills the room and rises rapidly upward.  The lake is
+fed by a stream, which tumbles out of a hole in the wall about 10 feet
+overhead and splashes noisily into the water somewhere within the
+mist.  There is a passage going back toward the south.
+
+> n'beh
+
+The waters have parted to form a narrow path across the reservoir.
+
+> n
+
+You are walking across the bottom of the reservoir.  Walls of water
+rear up on either side.  The roar of the water cascading past is
+nearly deafening, and the mist is so thick you can barely see.
+
+> n
+
+You are at the northern edge of the reservoir.  A northwest passage
+leads sharply up from here.
+
+The waters have parted to form a narrow path across the reservoir.
+
+> u
+
+You are scrambling along a treacherously steep, rocky passage.
+
+> u
+
+You are on a very steep incline, which widens at it goes upward.
+
+> u
+
+You are at the base of a nearly vertical cliff.  There are some
+slim footholds which would enable you to climb up, but it looks
+extremely dangerous.  Here at the base of the cliff lie the remains
+of several earlier adventurers who apparently failed to make it.
+
+> u
+
+You are climbing along a nearly vertical cliff.
+
+> u
+
+Just as you reach the top, your foot slips on a loose rock and you
+make one last desperate grab.  Your luck holds, as does your grip.
+With an enormous heave, you lift yourself to the ledge above.
+
+You are on a small ledge at the top of a nearly vertical cliff.
+There is a low crawl leading off to the northeast.
+
+> ne
+
+You have reached a dead end.
+
+There is a richly-carved ebony statuette here!
+
+> take statuette
+
+OK
+
+> sw
+
+You're at top of cliff.
+
+> d
+
+You are climbing along a nearly vertical cliff.
+
+> d
+
+You're at base of cliff.
+
+> d
+
+You are on a very steep incline, which widens at it goes upward.
+
+> d
+
+You are scrambling along a treacherously steep, rocky passage.
+
+> d
+
+You're north of reservoir.
+
+The waters have parted to form a narrow path across the reservoir.
+
+> s
+
+You're at bottom of reservoir.
+
+> s
+
+You're at reservoir.
+
+The waters have parted to form a narrow path across the reservoir.
+
+> s
+
+You are in a north/south canyon about 25 feet across.  The floor is
+covered by white mist seeping in from the north.  The walls extend
+upward for well over 100 feet.  Suspended from some unseen point far
+above you, an enormous two-sided mirror is hanging parallel to and
+midway between the canyon walls.  (The mirror is obviously provided
+for the use of the dwarves who, as you know, are extremely vain.)  A
+small window can be seen in either wall, some fifty feet up.
+
+> s
+
+You are in a secret n/s canyon above a large room.
+
+> d
+
+You are in a large low circular chamber whose floor is an immense slab
+fallen from the ceiling (Slab Room).  East and west there once were
+large passages, but they are now filled with boulders.  Low small
+passages go north and south, and the south one quickly bends west
+around the boulders.
+
+> s
+
+You're at west end of Twopit Room.
+
+The top of a 12-foot-tall beanstalk is poking out of the west pit.
+
+> d
+
+You're in west pit.
+
+There is a 12-foot-tall beanstalk stretching up out of the pit,
+bellowing "WATER!! WATER!!"
+
+> water plant
+
+The plant grows explosively, almost filling the bottom of the pit.
+
+You're in west pit.
+
+There is a gigantic beanstalk stretching all the way up to the hole.
+
+> u
+
+You're at west end of Twopit Room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> e
+
+You're at east end of Twopit Room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> d
+
+You're in east pit.
+
+> fill bottle
+
+Your bottle is now full of oil.
+
+> u
+
+You're at east end of Twopit Room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> w
+
+You're at west end of Twopit Room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> d
+
+You're in west pit.
+
+There is a gigantic beanstalk stretching all the way up to the hole.
+
+> climb
+
+You clamber up the plant and scurry through the hole at the top.
+
+You are in a long, narrow corridor stretching out of sight to the
+west.  At the eastern end is a hole through which you can see a
+profusion of leaves.
+
+> w
 
-You are in the ogre's storeroom.  The only exit is to the south.
+You are in the Giant Room.  The ceiling here is too high up for your
+lamp to show it.  Cavernous passages lead east, north, and south.  On
+the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic].
 
-There is an enormous ruby here!
+There is a large nest here, full of golden eggs!
 
-> take ruby
+> take eggs
 
 OK
 
-> s
+> n
 
-You are in a large chamber with passages to the west and north.
+You are at one end of an immense north/south passage.
 
-> w
+The way north is barred by a massive, rusty, iron door.
 
-You are in a long, rough-hewn, north/south corridor.
+> oil door
 
-> n
+The oil has freed up the hinges so that the door will now move,
+although it requires some effort.
 
-Dead end
+> drop bottle
 
-There is a massive vending machine here, swung back to reveal a
-southward passage.
+OK
 
 > n
 
-You are in a little maze of twisting passages, all different.
-
-> n
+You are in a magnificent cavern with a rushing stream, which cascades
+over a sparkling waterfall into a roaring whirlpool which disappears
+through a hole in the floor.  Passages exit to the south and west.
 
-You are in a little maze of twisty passages, all different.
+There is a jewel-encrusted trident here!
 
-> nw
+> take trident
 
-You are in a maze of twisty little passages, all different.
+OK
 
-> d
+> w
 
-You're at west end of long hall.
+You are at the top of a steep incline above a large room.  You could
+climb down here, but you would not be able to climb up.  There is a
+passage leading back to the north.
 
-> e
+> d
 
-You're at east end of long hall.
+You are in a large low room.  Crawls lead north, se, and sw.
 
-> e
+> bedquilt
 
-You're at west end of Hall of Mists.
+You're in Bedquilt.
 
 > e
 
-You're on west bank of fissure.
-
-There are diamonds here!
+You're at complex junction.
 
-A crystal bridge spans the fissure.
+> n
 
-> take diamonds
+You're in a large room carved out of sedimentary rock.  The floor and
+walls are littered with bits of shells embedded in the stone.  A
+shallow passage proceeds downward, and a somewhat steeper one leads
+up.  A low hands and knees passage enters from the south.
 
-OK
+There is an enormous clam here with its shell tightly closed.
 
-> e
+> open clam
 
-You're on east bank of fissure.
+A glistening pearl falls out of the clam and rolls away.  Goodness,
+this must really be an oyster.  (I never was very good at identifying
+bivalves.)  Whatever it is, it has now snapped shut again.
 
-A three foot black rod with a rusty star on an end lies nearby.
+> d
 
-A crystal bridge spans the fissure.
+You are in a long sloping corridor with ragged sharp walls.
 
-> e
+> d
 
-You're in Hall of Mists.
+You are in a cul-de-sac about eight feet across.
 
-Rough stone steps lead up the dome.
+Off to one side lies a glistening pearl!
 
-> drop bottle
+> take pearl
 
 OK
 
-> s
-
-This is a low room with a crude note on the wall.  The note says,
-"You won't get it up the steps".
+> shell
 
-There is a large sparkling nugget of gold here!
+You're in Shell Room.
 
-> take gold
+There is an enormous oyster here with its shell tightly closed.
 
-OK
+> s
 
-> n
+You're at complex junction.
 
-You're in Hall of Mists.
+> u
 
-There is a bottle of water here.
+You're in dusty rock room.
 
-> n
+> e
 
-You're in Hall of Mt King.
+You're in dirty passage.
 
-> n
+> u
 
 You're in n/s passage above e/w passage.
 
@@ -731,11 +1487,7 @@ You're in n/s passage above e/w passage.
 
 You're at "Y2".
 
-> off
-
-Your lamp is now off.
-
-It is now pitch dark.  If you proceed you will likely fall into a pit.
+There is a little axe here.
 
 > plugh
 
@@ -743,94 +1495,75 @@ It is now pitch dark.  If you proceed you will likely fall into a pit.
 
 You're inside building.
 
-There are bars of silver here!
+A brilliant blue star sapphire is here!
 
 There is a Persian rug spread out on the floor!
 
-There is precious jewelry here!
-
-A precious jade necklace has been dropped here!
-
-There are some keys on the ground here.
-
-There is food here.
+There is a rare amber gemstone here!
 
-> drop gold
+There is an enormous ruby here!
 
-OK
+There is an emerald here the size of a plover's egg!
 
-> drop diamonds
+The pirate's treasure chest is here!
 
-OK
+There is precious jewelry here!
 
-> drop pyramid
+There are diamonds here!
 
-OK
+There are many coins here!
 
-> drop ruby
+There are bars of silver here!
 
-OK
+There is a large sparkling nugget of gold here!
 
-> plugh
+A precious jade necklace has been dropped here!
 
->>Foof!<<
+There is a delicate, precious, ming vase here!
 
-It is now pitch dark.  If you proceed you will likely fall into a pit.
+A small velvet pillow lies on the floor.
 
-A hollow voice says "PLUGH".
+There is a platinum pyramid here, 8 inches on a side!
 
-> on
+There are some keys on the ground here.
 
-Your lamp is now on.
+There is food here.
 
-You're at "Y2".
+> drop trident
 
-> s
+OK
 
-You're in n/s passage above e/w passage.
+> drop pearl
 
-> s
+OK
 
-You are in the Hall of the Mountain King, with passages off in all
-directions.
+> drop statuette
 
-> u
+OK
 
-There is a threatening little dwarf in the room with you!
+> drop appendage
 
-You are at one end of a vast hall stretching forward out of sight to
-the west.  There are openings to either side.  Nearby, a wide stone
-staircase leads downward.  The hall is filled with wisps of white mist
-swaying to and fro almost as if alive.  A cold wind blows up the
-staircase.  There is a passage at the top of a dome behind you.
+OK
 
-There is a bottle of water here.
+> take keys
 
-Rough stone steps lead up the dome.
+OK
 
-> take water
+> take food
 
 OK
 
-> throw axe
+> plugh
 
-You killed a little dwarf.
+>>Foof!<<
 
-You're in Hall of Mists.
+You are in a large room, with a passage to the south, a passage to the
+west, and a wall of broken rock to the east.  There is a large "Y2" on
+a rock in the room's center.
 
 There is a little axe here.
 
-Rough stone steps lead up the dome.
-
-> take axe
-
-OK
-
-> n
-
-You're in Hall of Mt King.
-
-> n
+> s
 
 You are in a low n/s passage at a hole in the floor.  The hole goes
 down to an e/w passage.
@@ -841,201 +1574,201 @@ You're in dirty passage.
 
 > bedquilt
 
-You are in Bedquilt, a long east/west passage with holes everywhere.
-To explore at random select north, south, up, or down.
+You're in Bedquilt.
 
-> slab
+> w
 
-You are in a large low circular chamber whose floor is an immense slab
-fallen from the ceiling (Slab Room).  East and west there once were
-large passages, but they are now filled with boulders.  Low small
-passages go north and south, and the south one quickly bends west
-around the boulders.
+You're in Swiss Cheese Room.
 
-> s
+> oriental
 
-You are at the west end of the Twopit Room.  There is a large hole in
-the wall above the pit at this end of the room.
+You're in Oriental Room.
 
-> d
+> w
 
-You are at the bottom of the western pit in the Twopit Room.  There is
-a large hole in the wall about 25 feet above you.
+You're in large low room.
 
-There is a tiny little plant in the pit, murmuring "water, water, ..."
+> sw
 
-> water plant
+You are in a long winding corridor sloping out of sight in both
+directions.
 
-The plant spurts into furious growth for a few seconds.
+> u
 
-You're in west pit.
+You are on one side of a large, deep chasm.  A heavy white mist rising
+up from below obscures all view of the far side.  A sw path leads away
+from the chasm into a winding corridor.
 
-There is a 12-foot-tall beanstalk stretching up out of the pit,
-bellowing "WATER!! WATER!!"
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
 
-> u
+A burly troll stands by the bridge and insists you throw him a
+treasure before you may cross.
 
-You're at west end of Twopit Room.
+> throw eggs
 
-The top of a 12-foot-tall beanstalk is poking out of the west pit.
+The troll catches your treasure and scurries away out of sight.
 
-> w
+> ne
 
-You're in Slab Room.
+You are on the far side of the chasm.  A ne path leads away from the
+chasm on this side.
 
-> u
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
 
-You are in a secret n/s canyon above a large room.
+The troll is nowhere to be seen.
 
-> reservoir
+> barren
 
-You are at the edge of a large underground reservoir.  An opaque cloud
-of white mist fills the room and rises rapidly upward.  The lake is
-fed by a stream, which tumbles out of a hole in the wall about 10 feet
-overhead and splashes noisily into the water somewhere within the
-mist.  There is a passage going back toward the south.
+You are standing at the entrance to a large, barren room.  A notice
+above the entrance reads:  "Caution!  Bear in room!"
 
-> F'UNJ
+> e
 
-The waters have parted to form a narrow path across the reservoir.
+You are inside a barren room.  The center of the room is completely
+empty except for some dust.  Marks in the dust lead away toward the
+far end of the room.  The only exit is the way you came in.
 
-> n
+There is a ferocious cave bear eyeing you from the far end of the room!
 
-You are walking across the bottom of the reservoir.  Walls of water
-rear up on either side.  The roar of the water cascading past is
-nearly deafening, and the mist is so thick you can barely see.
+The bear is locked to the wall with a golden chain!
 
-> n
+> throw food
 
-You are at the northern edge of the reservoir.  A northwest passage
-leads sharply up from here.
+The bear eagerly wolfs down your food, after which he seems to calm
+down considerably and even becomes rather friendly.
 
-The waters have parted to form a narrow path across the reservoir.
+> unlock chain
 
-> nw
+The chain is now unlocked.
 
-You are scrambling along a treacherously steep, rocky passage.
+> take chain
 
-> u
+OK
 
-You are on a very steep incline, which widens at it goes upward.
+> take bear
 
-> u
+OK
 
-You are at the base of a nearly vertical cliff.  There are some
-slim footholds which would enable you to climb up, but it looks
-extremely dangerous.  Here at the base of the cliff lie the remains
-of several earlier adventurers who apparently failed to make it.
+> fork
 
-> u
+You are being followed by a very large, tame bear.
 
-You are climbing along a nearly vertical cliff.
+The path forks here.  The left fork leads northeast.  A dull rumbling
+seems to get louder in that direction.  The right fork leads southeast
+down a gentle slope.  The main corridor enters from the west.
 
-> u
+> ne
 
-Just as you reach the top, your foot slips on a loose rock and you
-make one last desperate grab.  Your luck holds, as does your grip.
-With an enormous heave, you lift yourself to the ledge above.
+You are being followed by a very large, tame bear.
 
-You are on a small ledge at the top of a nearly vertical cliff.
-There is a low crawl leading off to the northeast.
+The walls are quite warm here.  From the north can be heard a steady
+roar, so loud that the entire cave seems to be trembling.  Another
+passage leads south, and a low crawl goes east.
 
-> ne
+> fee
 
-You have reached a dead end.
+OK
 
-There is a richly-carved ebony statuette here!
+> fie
+
+OK
 
-> take ebony
+> foe
 
 OK
 
-> sw
+> foo
 
-You're at top of cliff.
+Done!
 
-> d
+> e
 
-You are climbing along a nearly vertical cliff.
+You are being followed by a very large, tame bear.
 
-> d
+You are in a small chamber filled with large boulders.  The walls are
+very warm, causing the air in the room to be almost stifling from the
+heat.  The only exit is a crawl heading west, through which is coming
+a low rumbling.
 
-You're at base of cliff.
+There are rare spices here!
 
-> d
+> take spices
 
-You are on a very steep incline, which widens at it goes upward.
+OK
 
-> d
+> fork
 
-You are scrambling along a treacherously steep, rocky passage.
+You are being followed by a very large, tame bear.
 
-> d
+You're at fork in path.
 
-You're north of reservoir.
+> w
 
-The waters have parted to form a narrow path across the reservoir.
+You are being followed by a very large, tame bear.
 
-> take water
+You're in a long east/west corridor.  A faint rumbling noise can be
+heard in the distance.
 
-Your bottle is now full of water.
+> w
 
-> s
+You are being followed by a very large, tame bear.
 
-You're at bottom of reservoir.
+You're on ne side of chasm.
 
-> s
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
 
-You're at reservoir.
+The troll is nowhere to be seen.
 
-The waters have parted to form a narrow path across the reservoir.
+> sw
 
-> s
+The troll steps out from beneath the bridge and blocks your way.
 
-You are in a north/south canyon about 25 feet across.  The floor is
-covered by white mist seeping in from the north.  The walls extend
-upward for well over 100 feet.  Suspended from some unseen point far
-above you, an enormous two-sided mirror is hanging parallel to and
-midway between the canyon walls.  (The mirror is obviously provided
-for the use of the dwarves who, as you know, are extremely vain.)  A
-small window can be seen in either wall, some fifty feet up.
+You are being followed by a very large, tame bear.
 
-> s
+You're on ne side of chasm.
 
-You are in a secret n/s canyon above a large room.
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
 
-> d
+A burly troll stands by the bridge and insists you throw him a
+treasure before you may cross.
 
-You're in Slab Room.
+> release bear
 
-> s
+The bear lumbers toward the troll, who lets out a startled shriek and
+scurries away.  The bear soon gives up the pursuit and wanders back.
 
-You're at west end of Twopit Room.
+> sw
 
-The top of a 12-foot-tall beanstalk is poking out of the west pit.
+You're on sw side of chasm.
 
-> d
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
 
-You're in west pit.
+The troll is nowhere to be seen.
 
-There is a 12-foot-tall beanstalk stretching up out of the pit,
-bellowing "WATER!! WATER!!"
+> sw
 
-> water plant
+You're in sloping corridor.
 
-The plant grows explosively, almost filling the bottom of the pit.
+> d
 
-You're in west pit.
+You're in large low room.
 
-There is a gigantic beanstalk stretching all the way up to the hole.
+> se
 
-> u
+You're in Oriental Room.
 
-You're at west end of Twopit Room.
+> se
 
-There is a huge beanstalk growing out of the west pit up to the hole.
+You are in a room whose walls resemble Swiss cheese.  Obvious passages
+go west, east, ne, and nw.  Part of the room is occupied by a large
+bedrock block.
 
-> e
+> w
 
 You are at the east end of the Twopit Room.  The floor here is
 littered with thin rock slabs, which make it easy to descend the pits.
@@ -1045,30 +1778,17 @@ wall directly over the west pit where you can't get to it.
 
 There is a huge beanstalk growing out of the west pit up to the hole.
 
-> d
-
-You are at the bottom of the eastern pit in the Twopit Room.  There is
-a small pool of oil in one corner of the pit.
-
-> get oil
-
-Your bottle is now full of oil.
-
-> u
-
-You're at east end of Twopit Room.
-
-There is a huge beanstalk growing out of the west pit up to the hole.
-
 > w
 
-You're at west end of Twopit Room.
+You are at the west end of the Twopit Room.  There is a large hole in
+the wall above the pit at this end of the room.
 
 There is a huge beanstalk growing out of the west pit up to the hole.
 
 > d
 
-You're in west pit.
+You are at the bottom of the western pit in the Twopit Room.  There is
+a large hole in the wall about 25 feet above you.
 
 There is a gigantic beanstalk stretching all the way up to the hole.
 
@@ -1076,231 +1796,291 @@ There is a gigantic beanstalk stretching all the way up to the hole.
 
 You clamber up the plant and scurry through the hole at the top.
 
-You are in a long, narrow corridor stretching out of sight to the
-west.  At the eastern end is a hole through which you can see a
-profusion of leaves.
+You're in narrow corridor.
 
 > w
 
-You are in the Giant Room.  The ceiling here is too high up for your
-lamp to show it.  Cavernous passages lead east, north, and south.  On
-the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic].
+You're in Giant Room.
 
 There is a large nest here, full of golden eggs!
 
+> take eggs
+
+OK
+
 > n
 
 You are at one end of an immense north/south passage.
 
-The way north is barred by a massive, rusty, iron door.
-
-> oil door
+There is an empty bottle here.
 
-The oil has freed up the hinges so that the door will now move,
-although it requires some effort.
+The way north leads through a massive, rusty, iron door.
 
-> drop bottle
+> n
 
-OK
+You're in cavern with waterfall.
 
-> drop appendage
+> w
 
-OK
+You're at steep incline above large room.
 
-> n
+> d
 
-You are in a magnificent cavern with a rushing stream, which cascades
-over a sparkling waterfall into a roaring whirlpool which disappears
-through a hole in the floor.  Passages exit to the south and west.
+You're in large low room.
 
-There is a jewel-encrusted trident here!
+> bedquilt
 
-> take trident
+You're in Bedquilt.
 
-OK
+> e
 
-> w
+You're at complex junction.
 
-You are at the top of a steep incline above a large room.  You could
-climb down here, but you would not be able to climb up.  There is a
-passage leading back to the north.
+> u
 
-> d
+You're in dusty rock room.
 
-You are in a large low room.  Crawls lead north, se, and sw.
+> e
 
-> se
+You're in dirty passage.
 
-This is the Oriental Room.  Ancient oriental cave drawings cover the
-walls.  A gently sloping passage leads upward to the north, another
-passage leads se, and a hands and knees crawl leads west.
+> u
 
-There is a delicate, precious, ming vase here!
+You're in n/s passage above e/w passage.
 
 > n
 
-You are following a wide path around the outer edge of a large cavern.
-Far below, through a heavy white mist, strange splashing noises can be
-heard.  The mist rises up through a fissure in the ceiling.  The path
-exits to the south and west.
+There is a threatening little dwarf in the room with you!
 
-> w
+One sharp nasty knife is thrown at you!
 
-You are in an alcove.  A small nw path seems to widen after a short
-distance.  An extremely tight tunnel leads east.  It looks like a very
-tight squeeze.  An eerie light can be seen at the other end.
+It misses!
 
-> inven
+You're at "Y2".
 
-You are currently holding the following:
-Brass lantern
-Dwarf's axe
-Jeweled trident
-Ebony statuette
+There is a little axe here.
 
-> drop trident
+> plugh
 
-OK
+>>Foof!<<
 
-> drop ebony
+You're inside building.
 
-OK
+Your keen eye spots a severed leporine appendage lying on the ground.
 
-> drop axe
+There is a richly-carved ebony statuette here!
 
-OK
+Off to one side lies a glistening pearl!
 
-> drop lantern
+There is a jewel-encrusted trident here!
 
-OK
+A brilliant blue star sapphire is here!
 
-> e
+There is a Persian rug spread out on the floor!
 
-You're in Plover Room.
+There is a rare amber gemstone here!
+
+There is an enormous ruby here!
 
 There is an emerald here the size of a plover's egg!
 
-> take emerald
+The pirate's treasure chest is here!
 
-OK
+There is precious jewelry here!
 
-> w
+There are diamonds here!
 
-You're in alcove.
+There are many coins here!
 
-There is a lamp shining nearby.
+There are bars of silver here!
 
-There is a little axe here.
+There is a large sparkling nugget of gold here!
 
-There is a richly-carved ebony statuette here!
+A precious jade necklace has been dropped here!
 
-There is a jewel-encrusted trident here!
+There is a delicate, precious, ming vase here!
 
-> take lamp
+A small velvet pillow lies on the floor.
 
-OK
+There is a platinum pyramid here, 8 inches on a side!
 
-> take axe
+> drop eggs
 
 OK
 
-> take ebony
+> drop chain
 
 OK
 
-> take trident
+> drop spices
 
 OK
 
-> nw
+> plugh
 
-You're in misty cavern.
+>>Foof!<<
+
+You're at "Y2".
+
+A hollow voice says "PLUGH".
+
+There is a little axe here.
 
 > s
 
-You're in Oriental Room.
+You're in n/s passage above e/w passage.
 
-There is a delicate, precious, ming vase here!
+> look
 
-> take vase
+Sorry, but I am not allowed to give more detail.  I will repeat the
+long description of your location.
 
-OK
+You are in a low n/s passage at a hole in the floor.  The hole goes
+down to an e/w passage.
 
-> se
+> look
 
-You are in a room whose walls resemble Swiss cheese.  Obvious passages
-go west, east, ne, and nw.  Part of the room is occupied by a large
-bedrock block.
+Sorry, but I am not allowed to give more detail.  I will repeat the
+long description of your location.
 
-> e
+You are in a low n/s passage at a hole in the floor.  The hole goes
+down to an e/w passage.
 
-You are in the Soft Room.  The walls are covered with heavy curtains,
-the floor with a thick pile carpet.  Moss covers the ceiling.
+> n
 
-A small velvet pillow lies on the floor.
+A sepulchral voice reverberating through the cave, says, "Cave closing
+soon.  All adventurers exit immediately through main office."
 
-> take pillow
+You're at "Y2".
 
-OK
+There is a little axe here.
+
+> plugh
+
+A mysterious recorded voice groans into life and announces:
+   "This exit is closed.  Please leave via main office."
+
+You're at "Y2".
+
+There is a little axe here.
+
+> s
+
+You're in n/s passage above e/w passage.
+
+> d
+
+You are in a dirty broken passage.  To the east is a crawl.  To the
+west is a large passage.  Above you is a hole to another passage.
 
 > w
 
-You're in Swiss Cheese Room.
+You're in dusty rock room.
 
-> ne
+> d
 
-You're in Bedquilt.
+You're at complex junction.
 
 > e
 
-You are at a complex junction.  A low hands and knees passage from the
-north joins a higher crawl from the east to make a walking passage
-going west.  There is also a large room above.  The air is damp here.
+You are in an anteroom leading to a large passage to the east.  Small
+passages go west and up.  The remnants of recent digging are evident.
+A sign in midair here says "Cave under construction beyond this point.
+Proceed at own risk.  [Witt Construction Company]"
 
-> n
+There are a few recent issues of "Spelunker Today" magazine here.
 
-You're in a large room carved out of sedimentary rock.  The floor and
-walls are littered with bits of shells embedded in the stone.  A
-shallow passage proceeds downward, and a somewhat steeper one leads
-up.  A low hands and knees passage enters from the south.
+> take magazine
 
-There is an enormous clam here with its shell tightly closed.
+OK
 
-> n
+> e
 
-There is no way to go that direction.
+You are at Witt's End.  Passages lead off in *ALL* directions.
 
-You're in Shell Room.
+> drop magazine
 
-There is an enormous clam here with its shell tightly closed.
+OK
 
-> seed 1635997320
+> look
 
-Seed set to 1635997320
+Sorry, but I am not allowed to give more detail.  I will repeat the
+long description of your location.
 
-You're in Shell Room.
+You are at Witt's End.  Passages lead off in *ALL* directions.
 
-There is an enormous clam here with its shell tightly closed.
+There are a few recent issues of "Spelunker Today" magazine here.
 
-> n
+> look
 
-There is no way to go that direction.
+You are at Witt's End.  Passages lead off in *ALL* directions.
 
-You're in Shell Room.
+There are a few recent issues of "Spelunker Today" magazine here.
 
-There is an enormous clam here with its shell tightly closed.
+> look
 
-> 
+You are at Witt's End.  Passages lead off in *ALL* directions.
 
-> 
+There are a few recent issues of "Spelunker Today" magazine here.
 
-> 
+> look
 
-> 
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> look
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+There are a few recent issues of "Spelunker Today" magazine here.
 
+> look
 
-You scored 179 out of a possible 430, using 216 turns.
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> look
+
+The sepulchral voice intones, "The cave is now closed."  As the echoes
+fade, there is a blinding flash of light (and a small puff of orange
+smoke). . . .    As your eyes refocus, you look around and find...
+
+You are at the northeast end of an immense room, even larger than the
+Giant Room.  It appears to be a repository for the "Adventure"
+program.  Massive torches far overhead bathe the room with smoky
+yellow light.  Scattered about you can be seen a pile of bottles (all
+of them empty), a nursery of young beanstalks murmuring quietly, a bed
+of oysters, a bundle of black rods with rusty stars on their ends, and
+a collection of brass lanterns.  Off to one side a great many dwarves
+are sleeping on the floor, snoring loudly.  A notice nearby reads: "Do
+not disturb the dwarves!"  An immense mirror is hanging against one
+wall, and stretches to the other end of the room, where various other
+sundry objects can be glimpsed dimly in the distance.
+
+> sw
+
+You are at the southwest end of the repository.  To one side is a pit
+full of fierce green snakes.  On the other side is a row of small
+wicker cages, each of which contains a little sulking bird.  In one
+corner is a bundle of black rods with rusty marks on their ends.  A
+large number of velvet pillows are scattered about on the floor.  A
+vast mirror stretches off to the northeast.  At your feet is a large
+steel grate, next to which is a sign that reads, "Treasure Vault.
+Keys in main office."
+
+The grate is locked.
+
+> take pillow
+
+OK
+
+> 
+
+> 
+You scored 391 out of a possible 430, using 345 turns.
 
-You may now consider yourself a "Seasoned Adventurer".
+Your score puts you in Master Adventurer Class B.
 
-To achieve the next higher rating, you need 72 more points.
+To achieve the next higher rating, you need 20 more points.
diff --git a/tests/stashed.log b/tests/stashed.log
new file mode 100644
index 0000000..0968282
--- /dev/null
+++ b/tests/stashed.log
@@ -0,0 +1,353 @@
+## Test picking up stashed objects in endgame
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+no
+seed 1318612053
+e
+plugh
+plove
+get emerald
+w
+drop emerald
+e
+ne
+get pyramid
+s
+plove
+plugh
+drop pyramid
+get lamp
+get water
+plugh
+on
+s
+d
+bedquilt
+w
+e
+take pillow
+w
+oriental
+take vase
+n
+w
+take emerald
+nw
+s
+se
+w
+w
+d
+water plant
+u
+e
+d
+fill bottle
+u
+e
+ne
+e
+u
+e
+u
+n
+plugh
+drop pillow
+drop vase
+drop bottle
+drop emerald
+xyzzy
+take rod
+e
+take cage
+pit
+drop rod
+e
+take bird
+w
+drop bird
+take rod
+wave rod
+take necklace
+drop rod
+take bird
+d
+s
+take nugget
+n
+n
+drop bird
+take bird
+sw
+w
+kill dragon
+yes
+drink blood
+take rug
+e
+e
+n
+take bars
+n
+plugh
+drop cage
+drop necklace
+drop nugget
+drop bars
+drop rug
+xyzzy
+pit
+take rod
+d
+w
+wave rod
+w
+take diamonds
+w
+w
+w
+s
+s
+e
+s
+hit machine
+s
+s
+kill ogre
+n
+take ruby
+s
+w
+n
+n
+sw
+w
+d
+n
+e
+take coins
+e
+s
+take jewelry
+n
+e
+w
+w
+w
+s
+e
+s
+s
+s
+n
+e
+e
+nw
+drop rod
+take jewelry
+take chest
+take ruby
+take diamonds
+take coins
+se
+w
+s
+d
+debris
+xyzzy
+off
+drop coins
+drop diamonds
+drop jewelry
+drop chest
+drop lamp
+take rug
+take emerald
+take cage
+take bottle
+w
+s
+w
+drop bird
+listen
+drop cage
+n
+take appendage
+n
+e
+n
+n
+fill urn
+light urn
+rub urn
+drop rug
+take amber
+drop emerald
+fly
+take sapphire
+fly
+take emerald
+drop ruby
+take rug
+take ruby
+e
+s
+e
+e
+e
+drop emerald
+drop ruby
+drop amber
+drop rug
+drop sapphire
+fill bottle
+take lamp
+plugh
+on
+s
+s
+sw
+w
+n
+reservoir
+n'beh
+n
+n
+u
+u
+u
+u
+u
+ne
+take statuette
+sw
+d
+d
+d
+d
+d
+s
+s
+s
+s
+d
+s
+d
+water plant
+u
+e
+d
+fill bottle
+u
+w
+d
+climb
+w
+take eggs
+n
+oil door
+drop bottle
+n
+take trident
+w
+d
+bedquilt
+e
+n
+open clam
+d
+d
+take pearl
+shell
+s
+u
+e
+u
+n
+plugh
+drop trident
+drop pearl
+drop statuette
+drop appendage
+take keys
+take food
+plugh
+s
+d
+bedquilt
+w
+oriental
+w
+sw
+u
+throw eggs
+ne
+barren
+e
+throw food
+unlock chain
+take chain
+take bear
+fork
+ne
+fee
+fie
+foe
+foo
+e
+take spices
+fork
+w
+w
+sw
+release bear
+sw
+sw
+d
+se
+se
+w
+w
+d
+climb
+w
+take eggs
+n
+n
+w
+d
+bedquilt
+e
+u
+e
+u
+n
+plugh
+drop eggs
+drop chain
+drop spices
+plugh
+s
+look
+look
+n
+plugh
+s
+d
+w
+d
+e
+take magazine
+e
+drop magazine
+look
+look
+look
+look
+look
+look
+look
+sw
+# Here we are
+take pillow
+
diff --git a/tests/takebird.chk b/tests/takebird.chk
new file mode 100644
index 0000000..6c6b64d
--- /dev/null
+++ b/tests/takebird.chk
@@ -0,0 +1,2084 @@
+
+Welcome to Adventure!!  Would you like instructions?
+
+> no
+
+You are standing at the end of a road before a small brick building.
+Around you is a forest.  A small stream flows out of the building and
+down a gully.
+
+> seed 1318612053
+
+Seed set to 1318612053
+
+You're in front of building.
+
+> e
+
+You are inside a building, a well house for a large spring.
+
+There are some keys on the ground here.
+
+There is a shiny brass lamp nearby.
+
+There is food here.
+
+There is a bottle of water here.
+
+> plugh
+
+>>Foof!<<
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> plove
+
+>>Foof!<<
+
+You're in a small chamber lit by an eerie green light.  An extremely
+narrow tunnel exits to the west.  A dark corridor leads ne.
+
+There is an emerald here the size of a plover's egg!
+
+> get emerald
+
+OK
+
+> w
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> drop emerald
+
+OK
+
+> e
+
+You're in Plover Room.
+
+> ne
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> get pyramid
+
+OK
+
+> s
+
+You're in Plover Room.
+
+> plove
+
+>>Foof!<<
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> plugh
+
+>>Foof!<<
+
+You're inside building.
+
+There are some keys on the ground here.
+
+There is a shiny brass lamp nearby.
+
+There is food here.
+
+There is a bottle of water here.
+
+> drop pyramid
+
+OK
+
+> get lamp
+
+OK
+
+> get water
+
+OK
+
+> plugh
+
+>>Foof!<<
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> on
+
+Your lamp is now on.
+
+You are in a large room, with a passage to the south, a passage to the
+west, and a wall of broken rock to the east.  There is a large "Y2" on
+a rock in the room's center.
+
+A hollow voice says "PLUGH".
+
+> s
+
+You are in a low n/s passage at a hole in the floor.  The hole goes
+down to an e/w passage.
+
+There are bars of silver here!
+
+> d
+
+You are in a dirty broken passage.  To the east is a crawl.  To the
+west is a large passage.  Above you is a hole to another passage.
+
+> bedquilt
+
+You are in Bedquilt, a long east/west passage with holes everywhere.
+To explore at random select north, south, up, or down.
+
+> w
+
+You are in a room whose walls resemble Swiss cheese.  Obvious passages
+go west, east, ne, and nw.  Part of the room is occupied by a large
+bedrock block.
+
+> e
+
+You are in the Soft Room.  The walls are covered with heavy curtains,
+the floor with a thick pile carpet.  Moss covers the ceiling.
+
+A small velvet pillow lies on the floor.
+
+> take pillow
+
+OK
+
+> w
+
+You're in Swiss Cheese Room.
+
+> oriental
+
+This is the Oriental Room.  Ancient oriental cave drawings cover the
+walls.  A gently sloping passage leads upward to the north, another
+passage leads se, and a hands and knees crawl leads west.
+
+There is a delicate, precious, ming vase here!
+
+> take vase
+
+OK
+
+> n
+
+You are following a wide path around the outer edge of a large cavern.
+Far below, through a heavy white mist, strange splashing noises can be
+heard.  The mist rises up through a fissure in the ceiling.  The path
+exits to the south and west.
+
+> w
+
+You are in an alcove.  A small nw path seems to widen after a short
+distance.  An extremely tight tunnel leads east.  It looks like a very
+tight squeeze.  An eerie light can be seen at the other end.
+
+There is an emerald here the size of a plover's egg!
+
+> take emerald
+
+OK
+
+> nw
+
+You're in misty cavern.
+
+> s
+
+You're in Oriental Room.
+
+> se
+
+You're in Swiss Cheese Room.
+
+> w
+
+You are at the east end of the Twopit Room.  The floor here is
+littered with thin rock slabs, which make it easy to descend the pits.
+There is a path here bypassing the pits to connect passages from east
+and west.  There are holes all over, but the only big one is on the
+wall directly over the west pit where you can't get to it.
+
+> w
+
+You are at the west end of the Twopit Room.  There is a large hole in
+the wall above the pit at this end of the room.
+
+> d
+
+You are at the bottom of the western pit in the Twopit Room.  There is
+a large hole in the wall about 25 feet above you.
+
+There is a tiny little plant in the pit, murmuring "water, water, ..."
+
+> water plant
+
+The plant spurts into furious growth for a few seconds.
+
+You're in west pit.
+
+There is a 12-foot-tall beanstalk stretching up out of the pit,
+bellowing "WATER!! WATER!!"
+
+> u
+
+You're at west end of Twopit Room.
+
+The top of a 12-foot-tall beanstalk is poking out of the west pit.
+
+> e
+
+You're at east end of Twopit Room.
+
+The top of a 12-foot-tall beanstalk is poking out of the west pit.
+
+> d
+
+You are at the bottom of the eastern pit in the Twopit Room.  There is
+a small pool of oil in one corner of the pit.
+
+> fill bottle
+
+Your bottle is now full of oil.
+
+> u
+
+You're at east end of Twopit Room.
+
+The top of a 12-foot-tall beanstalk is poking out of the west pit.
+
+> e
+
+You're in Swiss Cheese Room.
+
+> ne
+
+You're in Bedquilt.
+
+> e
+
+You are at a complex junction.  A low hands and knees passage from the
+north joins a higher crawl from the east to make a walking passage
+going west.  There is also a large room above.  The air is damp here.
+
+> u
+
+You are in a large room full of dusty rocks.  There is a big hole in
+the floor.  There are cracks everywhere, and a passage leading east.
+
+> e
+
+You're in dirty passage.
+
+> u
+
+You're in n/s passage above e/w passage.
+
+There are bars of silver here!
+
+> n
+
+A little dwarf just walked around a corner, saw you, threw a little
+axe at you which missed, cursed, and ran away.
+
+You're at "Y2".
+
+There is a little axe here.
+
+> plugh
+
+>>Foof!<<
+
+You're inside building.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+There are some keys on the ground here.
+
+There is food here.
+
+> drop pillow
+
+OK
+
+> drop vase
+
+The vase is now resting, delicately, on a velvet pillow.
+
+> drop bottle
+
+OK
+
+> drop emerald
+
+OK
+
+> xyzzy
+
+>>Foof!<<
+
+You are in a debris room filled with stuff washed in from the surface.
+A low wide passage with cobbles becomes plugged with mud and debris
+here, but an awkward canyon leads upward and west.  In the mud someone
+has scrawled, "MAGIC WORD XYZZY".
+
+A three foot black rod with a rusty star on an end lies nearby.
+
+> take rod
+
+OK
+
+> e
+
+You are crawling over cobbles in a low passage.  There is a dim light
+at the east end of the passage.
+
+There is a small wicker cage discarded nearby.
+
+> take cage
+
+OK
+
+> pit
+
+At your feet is a small pit breathing traces of white mist.  An east
+passage ends here except for a small crack leading on.
+
+Rough stone steps lead down the pit.
+
+> drop rod
+
+OK
+
+> e
+
+You are in a splendid chamber thirty feet high.  The walls are frozen
+rivers of orange stone.  An awkward canyon and a good passage exit
+from east and west sides of the chamber.
+
+A cheerful little bird is sitting here singing.
+
+> take bird
+
+OK
+
+> w
+
+You're at top of small pit.
+
+A three foot black rod with a rusty star on an end lies nearby.
+
+Rough stone steps lead down the pit.
+
+> drop bird
+
+OK
+
+> take rod
+
+OK
+
+> wave rod
+
+The bird flies about agitatedly for a moment, then disappears through
+the crack.  It reappears shortly, carrying in its beak a jade
+necklace, which it drops at your feet.
+
+> take necklace
+
+OK
+
+> drop rod
+
+OK
+
+> take bird
+
+OK
+
+> d
+
+You are at one end of a vast hall stretching forward out of sight to
+the west.  There are openings to either side.  Nearby, a wide stone
+staircase leads downward.  The hall is filled with wisps of white mist
+swaying to and fro almost as if alive.  A cold wind blows up the
+staircase.  There is a passage at the top of a dome behind you.
+
+Rough stone steps lead up the dome.
+
+> s
+
+This is a low room with a crude note on the wall.  The note says,
+"You won't get it up the steps".
+
+There is a large sparkling nugget of gold here!
+
+> take nugget
+
+OK
+
+> n
+
+You're in Hall of Mists.
+
+> n
+
+You are in the Hall of the Mountain King, with passages off in all
+directions.
+
+A huge green fierce snake bars the way!
+
+> drop bird
+
+The little bird attacks the green snake, and in an astounding flurry
+drives the snake away.
+
+> take bird
+
+OK
+
+> sw
+
+You are in a secret canyon which here runs e/w.  It crosses over a
+very tight canyon 15 feet below.  If you go down you may not be able
+to get back up.
+
+> w
+
+You are in a secret canyon which exits to the north and east.
+
+A huge green fierce dragon bars the way!
+
+The dragon is sprawled out on a Persian rug!!
+
+> kill dragon
+
+With what?  Your bare hands?
+
+> yes
+
+Congratulations!  You have just vanquished a dragon with your bare
+hands!  (Unbelievable, isn't it?)
+
+You are in a secret canyon which exits to the north and east.
+
+There is a Persian rug spread out on the floor!
+
+The blood-specked body of a huge green dead dragon lies to one side.
+
+> drink blood
+
+Your head buzzes strangely for a moment.
+
+> take rug
+
+OK
+
+> e
+
+You're in secret e/w canyon above tight canyon.
+
+> e
+
+You're in Hall of Mt King.
+
+> n
+
+You're in n/s passage above e/w passage.
+
+There are bars of silver here!
+
+> take bars
+
+OK
+
+> n
+
+You're at "Y2".
+
+There is a little axe here.
+
+> plugh
+
+>>Foof!<<
+
+You're inside building.
+
+There is an emerald here the size of a plover's egg!
+
+There is a bottle of oil here.
+
+There is a delicate, precious, ming vase here!
+
+A small velvet pillow lies on the floor.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+There are some keys on the ground here.
+
+There is food here.
+
+> drop cage
+
+OK
+
+> drop necklace
+
+OK
+
+> drop nugget
+
+OK
+
+> drop bars
+
+OK
+
+> drop rug
+
+OK
+
+> xyzzy
+
+>>Foof!<<
+
+You're in debris room.
+
+> pit
+
+You're at top of small pit.
+
+A three foot black rod with a rusty star on an end lies nearby.
+
+Rough stone steps lead down the pit.
+
+> take rod
+
+OK
+
+> d
+
+You're in Hall of Mists.
+
+Rough stone steps lead up the dome.
+
+> w
+
+You are on the east bank of a fissure slicing clear across the hall.
+The mist is quite thick here, and the fissure is too wide to jump.
+
+> wave rod
+
+A crystal bridge now spans the fissure.
+
+> w
+
+You are on the west side of the fissure in the Hall of Mists.
+
+There are diamonds here!
+
+A crystal bridge spans the fissure.
+
+> take diamonds
+
+OK
+
+> w
+
+There is a threatening little dwarf in the room with you!
+
+You are at the west end of the Hall of Mists.  A low wide crawl
+continues west and another goes north.  To the south is a little
+passage 6 feet off the floor.
+
+> w
+
+There is a threatening little dwarf in the room with you!
+
+You are at the east end of a very long hall apparently without side
+chambers.  To the east a low wide crawl slants up.  To the north a
+round two foot hole slants down.
+
+> w
+
+There is a threatening little dwarf in the room with you!
+
+You are at the west end of a very long featureless hall.  The hall
+joins up with a narrow north/south passage.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+You are in a maze of twisty little passages, all different.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+You are in a maze of twisting little passages, all different.
+
+> e
+
+There is a threatening little dwarf in the room with you!
+
+You are in a little maze of twisting passages, all different.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+Dead end
+
+There is a massive and somewhat battered vending machine here.  The
+instructions on it read: "Drop coins here to receive fresh batteries."
+
+> hit machine
+
+As you strike the vending machine, it pivots backward along with a
+section of wall, revealing a dark passage leading south.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+You are in a long, rough-hewn, north/south corridor.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+You are in a large chamber with passages to the west and north.
+
+A formidable ogre bars the northern exit.
+
+> kill ogre
+
+The ogre, who despite his bulk is quite agile, easily dodges your
+attack.  He seems almost amused by your puny effort.
+
+One sharp nasty knife is thrown at you!
+
+The ogre, distracted by your rush, is struck by the knife.  With a
+blood-curdling yell he turns and bounds after the dwarf, who flees
+in panic.  You are left alone in the room.
+
+> n
+
+You are in the ogre's storeroom.  The only exit is to the south.
+
+There is an enormous ruby here!
+
+> take ruby
+
+OK
+
+> s
+
+You are in a large chamber with passages to the west and north.
+
+> w
+
+You are in a long, rough-hewn, north/south corridor.
+
+> n
+
+Dead end
+
+There is a massive vending machine here, swung back to reveal a
+southward passage.
+
+> n
+
+You are in a little maze of twisting passages, all different.
+
+> sw
+
+You are in a maze of twisting little passages, all different.
+
+> w
+
+You are in a maze of twisty little passages, all different.
+
+> d
+
+You're at west end of long hall.
+
+> n
+
+You are at a crossover of a high n/s passage and a low e/w one.
+
+> e
+
+You are in the west side chamber of the Hall of the Mountain King.
+A passage continues west and up here.
+
+There are many coins here!
+
+> take coins
+
+OK
+
+> e
+
+You're in Hall of Mt King.
+
+> s
+
+You are in the south side chamber.
+
+There is precious jewelry here!
+
+> take jewelry
+
+OK
+
+> n
+
+You're in Hall of Mt King.
+
+> e
+
+You're in Hall of Mists.
+
+Rough stone steps lead up the dome.
+
+> w
+
+You're on east bank of fissure.
+
+A crystal bridge spans the fissure.
+
+> w
+
+You're on west bank of fissure.
+
+A crystal bridge spans the fissure.
+
+> w
+
+You're at west end of Hall of Mists.
+
+> s
+
+You are in a maze of twisty little passages, all alike.
+
+> e
+
+Out from the shadows behind you pounces a bearded pirate!  "Har, har,"
+he chortles, "I'll just take all this booty and hide it away with me
+chest deep in the maze!"  He snatches your treasure and vanishes into
+the gloom.
+
+You are in a maze of twisty little passages, all alike.
+
+> s
+
+You are in a maze of twisty little passages, all alike.
+
+> s
+
+You are in a maze of twisty little passages, all alike.
+
+> s
+
+You are in a maze of twisty little passages, all alike.
+
+> n
+
+You are in a maze of twisty little passages, all alike.
+
+> e
+
+You are on the brink of a thirty foot pit with a massive orange column
+down one wall.  You could climb down here but you could not get back
+up.  The maze continues at this level.
+
+> e
+
+You are in a maze of twisty little passages, all alike.
+
+> nw
+
+Dead end
+
+There is an enormous ruby here!
+
+There are many coins here!
+
+There is precious jewelry here!
+
+There are diamonds here!
+
+The pirate's treasure chest is here!
+
+> drop rod
+
+OK
+
+> take jewelry
+
+OK
+
+> take chest
+
+OK
+
+> take ruby
+
+OK
+
+> take diamonds
+
+OK
+
+> take coins
+
+OK
+
+> se
+
+There is a threatening little dwarf in the room with you!
+
+You are in a maze of twisty little passages, all alike.
+
+> w
+
+There is a threatening little dwarf in the room with you!
+
+You are in a maze of twisty little passages, all alike.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+You're at brink of pit.
+
+> d
+
+You're in bird chamber.
+
+> debris
+
+You're in debris room.
+
+> xyzzy
+
+>>Foof!<<
+
+You're inside building.
+
+There is a Persian rug spread out on the floor!
+
+There are bars of silver here!
+
+There is a large sparkling nugget of gold here!
+
+A precious jade necklace has been dropped here!
+
+There is a small wicker cage discarded nearby.
+
+There is a little bird in the cage.
+
+There is an emerald here the size of a plover's egg!
+
+There is a bottle of oil here.
+
+There is a delicate, precious, ming vase here!
+
+A small velvet pillow lies on the floor.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+There are some keys on the ground here.
+
+There is food here.
+
+> off
+
+Your lamp is now off.
+
+> drop coins
+
+OK
+
+> drop diamonds
+
+OK
+
+> drop jewelry
+
+OK
+
+> drop chest
+
+OK
+
+> drop lamp
+
+OK
+
+> take rug
+
+OK
+
+> take emerald
+
+OK
+
+> take cage
+
+OK
+
+> take bottle
+
+OK
+
+> w
+
+You're in front of building.
+
+> s
+
+You are in a valley in the forest beside a stream tumbling along a
+rocky bed.
+
+> w
+
+You are wandering aimlessly through the forest.
+
+> drop bird
+
+OK
+
+> listen
+
+The bird is singing to you in gratitude for your having returned it to
+its home.  In return, it informs you of a magic word which it thinks
+you may find useful somewhere near the Hall of Mists.  The magic word
+changes frequently, but for now the bird believes it is "N'BEH".  You
+thank the bird for this information, and it flies off into the forest.
+
+> drop cage
+
+OK
+
+> n
+
+You are wandering aimlessly through the forest.
+
+Your keen eye spots a severed leporine appendage lying on the ground.
+
+> take appendage
+
+OK
+
+> n
+
+You are wandering aimlessly through the forest.
+
+> e
+
+You are wandering aimlessly through the forest.
+
+> n
+
+You are wandering aimlessly through the forest.
+
+> n
+
+The forest thins out here to reveal a steep cliff.  There is no way
+down, but a small ledge can be seen to the west across the chasm.
+
+A small urn is embedded in the rock.
+
+> fill urn
+
+Your bottle is now empty and the urn is full of oil.
+
+> light urn
+
+The urn is now lit.
+
+> rub urn
+
+As you rub the urn, there is a flash of light and a genie appears.
+His aspect is stern as he advises: "One who wouldst traffic in
+precious stones must first learn to recognize the signals thereof."
+He wrests the urn from the stone, leaving a small cavity.  Turning to
+face you again, he fixes you with a steely eye and intones: "Caution!"
+Genie and urn vanish in a cloud of amber smoke.  The smoke condenses
+to form a rare amber gemstone, resting in the cavity in the rock.
+
+> drop rug
+
+OK
+
+> take amber
+
+OK
+
+> drop emerald
+
+The gem fits easily into the cavity.
+
+The Persian rug stiffens and rises a foot or so off the ground.
+
+> fly
+
+You board the Persian rug, which promptly whisks you across the chasm.
+You have time for a fleeting glimpse of a two thousand foot drop to a
+mighty river; then you find yourself on the other side.
+
+You are on a small ledge on one face of a sheer cliff.  There are no
+paths away from the ledge.  Across the chasm is a small clearing
+surrounded by forest.
+
+There is a Persian rug here, hovering in mid-air!
+
+A brilliant blue star sapphire is here!
+
+> take sapphire
+
+OK
+
+> fly
+
+The rug ferries you back across the chasm.
+
+You're at cliff.
+
+There is an emerald resting in a small cavity in the rock!
+
+There is a Persian rug here, hovering in mid-air!
+
+> take emerald
+
+OK
+
+> drop ruby
+
+The gem fits easily into the cavity.
+
+The Persian rug settles gently to the ground.
+
+> take rug
+
+OK
+
+> take ruby
+
+OK
+
+> e
+
+You are wandering aimlessly through the forest.
+
+> s
+
+You are wandering aimlessly through the forest.
+
+> e
+
+You have walked up a hill, still in the forest.  The road slopes back
+down the other side of the hill.  There is a building in the distance.
+
+> e
+
+You're in front of building.
+
+> e
+
+You are inside a building, a well house for a large spring.
+
+There is a shiny brass lamp nearby.
+
+The pirate's treasure chest is here!
+
+There is precious jewelry here!
+
+There are diamonds here!
+
+There are many coins here!
+
+There are bars of silver here!
+
+There is a large sparkling nugget of gold here!
+
+A precious jade necklace has been dropped here!
+
+There is a delicate, precious, ming vase here!
+
+A small velvet pillow lies on the floor.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+There are some keys on the ground here.
+
+There is food here.
+
+> drop emerald
+
+OK
+
+> drop ruby
+
+OK
+
+> drop amber
+
+OK
+
+> drop rug
+
+OK
+
+> drop sapphire
+
+OK
+
+> fill bottle
+
+Your bottle is now full of water.
+
+> take lamp
+
+OK
+
+> plugh
+
+>>Foof!<<
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> on
+
+Your lamp is now on.
+
+You're at "Y2".
+
+There is a little axe here.
+
+> s
+
+You're in n/s passage above e/w passage.
+
+> s
+
+You're in Hall of Mt King.
+
+> sw
+
+You're in secret e/w canyon above tight canyon.
+
+> w
+
+You are in a secret canyon which exits to the north and east.
+
+The body of a huge green dead dragon is lying off to one side.
+
+> n
+
+You are in a secret n/s canyon above a large room.
+
+> reservoir
+
+You are at the edge of a large underground reservoir.  An opaque cloud
+of white mist fills the room and rises rapidly upward.  The lake is
+fed by a stream, which tumbles out of a hole in the wall about 10 feet
+overhead and splashes noisily into the water somewhere within the
+mist.  There is a passage going back toward the south.
+
+> n'beh
+
+The waters have parted to form a narrow path across the reservoir.
+
+> n
+
+You are walking across the bottom of the reservoir.  Walls of water
+rear up on either side.  The roar of the water cascading past is
+nearly deafening, and the mist is so thick you can barely see.
+
+> n
+
+You are at the northern edge of the reservoir.  A northwest passage
+leads sharply up from here.
+
+The waters have parted to form a narrow path across the reservoir.
+
+> u
+
+You are scrambling along a treacherously steep, rocky passage.
+
+> u
+
+You are on a very steep incline, which widens at it goes upward.
+
+> u
+
+You are at the base of a nearly vertical cliff.  There are some
+slim footholds which would enable you to climb up, but it looks
+extremely dangerous.  Here at the base of the cliff lie the remains
+of several earlier adventurers who apparently failed to make it.
+
+> u
+
+You are climbing along a nearly vertical cliff.
+
+> u
+
+Just as you reach the top, your foot slips on a loose rock and you
+make one last desperate grab.  Your luck holds, as does your grip.
+With an enormous heave, you lift yourself to the ledge above.
+
+You are on a small ledge at the top of a nearly vertical cliff.
+There is a low crawl leading off to the northeast.
+
+> ne
+
+You have reached a dead end.
+
+There is a richly-carved ebony statuette here!
+
+> take statuette
+
+OK
+
+> sw
+
+You're at top of cliff.
+
+> d
+
+You are climbing along a nearly vertical cliff.
+
+> d
+
+You're at base of cliff.
+
+> d
+
+You are on a very steep incline, which widens at it goes upward.
+
+> d
+
+You are scrambling along a treacherously steep, rocky passage.
+
+> d
+
+You're north of reservoir.
+
+The waters have parted to form a narrow path across the reservoir.
+
+> s
+
+You're at bottom of reservoir.
+
+> s
+
+You're at reservoir.
+
+The waters have parted to form a narrow path across the reservoir.
+
+> s
+
+You are in a north/south canyon about 25 feet across.  The floor is
+covered by white mist seeping in from the north.  The walls extend
+upward for well over 100 feet.  Suspended from some unseen point far
+above you, an enormous two-sided mirror is hanging parallel to and
+midway between the canyon walls.  (The mirror is obviously provided
+for the use of the dwarves who, as you know, are extremely vain.)  A
+small window can be seen in either wall, some fifty feet up.
+
+> s
+
+You are in a secret n/s canyon above a large room.
+
+> d
+
+You are in a large low circular chamber whose floor is an immense slab
+fallen from the ceiling (Slab Room).  East and west there once were
+large passages, but they are now filled with boulders.  Low small
+passages go north and south, and the south one quickly bends west
+around the boulders.
+
+> s
+
+You're at west end of Twopit Room.
+
+The top of a 12-foot-tall beanstalk is poking out of the west pit.
+
+> d
+
+You're in west pit.
+
+There is a 12-foot-tall beanstalk stretching up out of the pit,
+bellowing "WATER!! WATER!!"
+
+> water plant
+
+The plant grows explosively, almost filling the bottom of the pit.
+
+You're in west pit.
+
+There is a gigantic beanstalk stretching all the way up to the hole.
+
+> u
+
+You're at west end of Twopit Room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> e
+
+You're at east end of Twopit Room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> d
+
+You're in east pit.
+
+> fill bottle
+
+Your bottle is now full of oil.
+
+> u
+
+You're at east end of Twopit Room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> w
+
+You're at west end of Twopit Room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> d
+
+You're in west pit.
+
+There is a gigantic beanstalk stretching all the way up to the hole.
+
+> climb
+
+You clamber up the plant and scurry through the hole at the top.
+
+You are in a long, narrow corridor stretching out of sight to the
+west.  At the eastern end is a hole through which you can see a
+profusion of leaves.
+
+> w
+
+You are in the Giant Room.  The ceiling here is too high up for your
+lamp to show it.  Cavernous passages lead east, north, and south.  On
+the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic].
+
+There is a large nest here, full of golden eggs!
+
+> take eggs
+
+OK
+
+> n
+
+You are at one end of an immense north/south passage.
+
+The way north is barred by a massive, rusty, iron door.
+
+> oil door
+
+The oil has freed up the hinges so that the door will now move,
+although it requires some effort.
+
+> drop bottle
+
+OK
+
+> n
+
+You are in a magnificent cavern with a rushing stream, which cascades
+over a sparkling waterfall into a roaring whirlpool which disappears
+through a hole in the floor.  Passages exit to the south and west.
+
+There is a jewel-encrusted trident here!
+
+> take trident
+
+OK
+
+> w
+
+You are at the top of a steep incline above a large room.  You could
+climb down here, but you would not be able to climb up.  There is a
+passage leading back to the north.
+
+> d
+
+You are in a large low room.  Crawls lead north, se, and sw.
+
+> bedquilt
+
+You're in Bedquilt.
+
+> e
+
+You're at complex junction.
+
+> n
+
+You're in a large room carved out of sedimentary rock.  The floor and
+walls are littered with bits of shells embedded in the stone.  A
+shallow passage proceeds downward, and a somewhat steeper one leads
+up.  A low hands and knees passage enters from the south.
+
+There is an enormous clam here with its shell tightly closed.
+
+> open clam
+
+A glistening pearl falls out of the clam and rolls away.  Goodness,
+this must really be an oyster.  (I never was very good at identifying
+bivalves.)  Whatever it is, it has now snapped shut again.
+
+> d
+
+You are in a long sloping corridor with ragged sharp walls.
+
+> d
+
+You are in a cul-de-sac about eight feet across.
+
+Off to one side lies a glistening pearl!
+
+> take pearl
+
+OK
+
+> shell
+
+You're in Shell Room.
+
+There is an enormous oyster here with its shell tightly closed.
+
+> s
+
+You're at complex junction.
+
+> u
+
+You're in dusty rock room.
+
+> e
+
+You're in dirty passage.
+
+> u
+
+You're in n/s passage above e/w passage.
+
+> n
+
+You're at "Y2".
+
+There is a little axe here.
+
+> plugh
+
+>>Foof!<<
+
+You're inside building.
+
+A brilliant blue star sapphire is here!
+
+There is a Persian rug spread out on the floor!
+
+There is a rare amber gemstone here!
+
+There is an enormous ruby here!
+
+There is an emerald here the size of a plover's egg!
+
+The pirate's treasure chest is here!
+
+There is precious jewelry here!
+
+There are diamonds here!
+
+There are many coins here!
+
+There are bars of silver here!
+
+There is a large sparkling nugget of gold here!
+
+A precious jade necklace has been dropped here!
+
+There is a delicate, precious, ming vase here!
+
+A small velvet pillow lies on the floor.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+There are some keys on the ground here.
+
+There is food here.
+
+> drop trident
+
+OK
+
+> drop pearl
+
+OK
+
+> drop statuette
+
+OK
+
+> drop appendage
+
+OK
+
+> take keys
+
+OK
+
+> take food
+
+OK
+
+> plugh
+
+>>Foof!<<
+
+You are in a large room, with a passage to the south, a passage to the
+west, and a wall of broken rock to the east.  There is a large "Y2" on
+a rock in the room's center.
+
+There is a little axe here.
+
+> s
+
+You are in a low n/s passage at a hole in the floor.  The hole goes
+down to an e/w passage.
+
+> d
+
+You're in dirty passage.
+
+> bedquilt
+
+You're in Bedquilt.
+
+> w
+
+You're in Swiss Cheese Room.
+
+> oriental
+
+You're in Oriental Room.
+
+> w
+
+You're in large low room.
+
+> sw
+
+You are in a long winding corridor sloping out of sight in both
+directions.
+
+> u
+
+You are on one side of a large, deep chasm.  A heavy white mist rising
+up from below obscures all view of the far side.  A sw path leads away
+from the chasm into a winding corridor.
+
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
+
+A burly troll stands by the bridge and insists you throw him a
+treasure before you may cross.
+
+> throw eggs
+
+The troll catches your treasure and scurries away out of sight.
+
+> ne
+
+You are on the far side of the chasm.  A ne path leads away from the
+chasm on this side.
+
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
+
+The troll is nowhere to be seen.
+
+> barren
+
+You are standing at the entrance to a large, barren room.  A notice
+above the entrance reads:  "Caution!  Bear in room!"
+
+> e
+
+You are inside a barren room.  The center of the room is completely
+empty except for some dust.  Marks in the dust lead away toward the
+far end of the room.  The only exit is the way you came in.
+
+There is a ferocious cave bear eyeing you from the far end of the room!
+
+The bear is locked to the wall with a golden chain!
+
+> throw food
+
+The bear eagerly wolfs down your food, after which he seems to calm
+down considerably and even becomes rather friendly.
+
+> unlock chain
+
+The chain is now unlocked.
+
+> take chain
+
+OK
+
+> take bear
+
+OK
+
+> fork
+
+You are being followed by a very large, tame bear.
+
+The path forks here.  The left fork leads northeast.  A dull rumbling
+seems to get louder in that direction.  The right fork leads southeast
+down a gentle slope.  The main corridor enters from the west.
+
+> ne
+
+You are being followed by a very large, tame bear.
+
+The walls are quite warm here.  From the north can be heard a steady
+roar, so loud that the entire cave seems to be trembling.  Another
+passage leads south, and a low crawl goes east.
+
+> fee
+
+OK
+
+> fie
+
+OK
+
+> foe
+
+OK
+
+> foo
+
+Done!
+
+> e
+
+You are being followed by a very large, tame bear.
+
+You are in a small chamber filled with large boulders.  The walls are
+very warm, causing the air in the room to be almost stifling from the
+heat.  The only exit is a crawl heading west, through which is coming
+a low rumbling.
+
+There are rare spices here!
+
+> take spices
+
+OK
+
+> fork
+
+You are being followed by a very large, tame bear.
+
+You're at fork in path.
+
+> w
+
+You are being followed by a very large, tame bear.
+
+You're in a long east/west corridor.  A faint rumbling noise can be
+heard in the distance.
+
+> w
+
+You are being followed by a very large, tame bear.
+
+You're on ne side of chasm.
+
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
+
+The troll is nowhere to be seen.
+
+> sw
+
+The troll steps out from beneath the bridge and blocks your way.
+
+You are being followed by a very large, tame bear.
+
+You're on ne side of chasm.
+
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
+
+A burly troll stands by the bridge and insists you throw him a
+treasure before you may cross.
+
+> release bear
+
+The bear lumbers toward the troll, who lets out a startled shriek and
+scurries away.  The bear soon gives up the pursuit and wanders back.
+
+> sw
+
+You're on sw side of chasm.
+
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
+
+The troll is nowhere to be seen.
+
+> sw
+
+You're in sloping corridor.
+
+> d
+
+You're in large low room.
+
+> se
+
+You're in Oriental Room.
+
+> se
+
+You are in a room whose walls resemble Swiss cheese.  Obvious passages
+go west, east, ne, and nw.  Part of the room is occupied by a large
+bedrock block.
+
+> w
+
+You are at the east end of the Twopit Room.  The floor here is
+littered with thin rock slabs, which make it easy to descend the pits.
+There is a path here bypassing the pits to connect passages from east
+and west.  There are holes all over, but the only big one is on the
+wall directly over the west pit where you can't get to it.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> w
+
+You are at the west end of the Twopit Room.  There is a large hole in
+the wall above the pit at this end of the room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> d
+
+You are at the bottom of the western pit in the Twopit Room.  There is
+a large hole in the wall about 25 feet above you.
+
+There is a gigantic beanstalk stretching all the way up to the hole.
+
+> climb
+
+You clamber up the plant and scurry through the hole at the top.
+
+You're in narrow corridor.
+
+> w
+
+You're in Giant Room.
+
+There is a large nest here, full of golden eggs!
+
+> take eggs
+
+OK
+
+> n
+
+You are at one end of an immense north/south passage.
+
+There is an empty bottle here.
+
+The way north leads through a massive, rusty, iron door.
+
+> n
+
+You're in cavern with waterfall.
+
+> w
+
+You're at steep incline above large room.
+
+> d
+
+You're in large low room.
+
+> bedquilt
+
+You're in Bedquilt.
+
+> e
+
+You're at complex junction.
+
+> u
+
+You're in dusty rock room.
+
+> e
+
+You're in dirty passage.
+
+> u
+
+You're in n/s passage above e/w passage.
+
+> n
+
+There is a threatening little dwarf in the room with you!
+
+One sharp nasty knife is thrown at you!
+
+It misses!
+
+You're at "Y2".
+
+There is a little axe here.
+
+> plugh
+
+>>Foof!<<
+
+You're inside building.
+
+Your keen eye spots a severed leporine appendage lying on the ground.
+
+There is a richly-carved ebony statuette here!
+
+Off to one side lies a glistening pearl!
+
+There is a jewel-encrusted trident here!
+
+A brilliant blue star sapphire is here!
+
+There is a Persian rug spread out on the floor!
+
+There is a rare amber gemstone here!
+
+There is an enormous ruby here!
+
+There is an emerald here the size of a plover's egg!
+
+The pirate's treasure chest is here!
+
+There is precious jewelry here!
+
+There are diamonds here!
+
+There are many coins here!
+
+There are bars of silver here!
+
+There is a large sparkling nugget of gold here!
+
+A precious jade necklace has been dropped here!
+
+There is a delicate, precious, ming vase here!
+
+A small velvet pillow lies on the floor.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+> drop eggs
+
+OK
+
+> drop chain
+
+OK
+
+> drop spices
+
+OK
+
+> plugh
+
+>>Foof!<<
+
+You're at "Y2".
+
+A hollow voice says "PLUGH".
+
+There is a little axe here.
+
+> s
+
+You're in n/s passage above e/w passage.
+
+> look
+
+Sorry, but I am not allowed to give more detail.  I will repeat the
+long description of your location.
+
+You are in a low n/s passage at a hole in the floor.  The hole goes
+down to an e/w passage.
+
+> look
+
+Sorry, but I am not allowed to give more detail.  I will repeat the
+long description of your location.
+
+You are in a low n/s passage at a hole in the floor.  The hole goes
+down to an e/w passage.
+
+> n
+
+A sepulchral voice reverberating through the cave, says, "Cave closing
+soon.  All adventurers exit immediately through main office."
+
+You're at "Y2".
+
+There is a little axe here.
+
+> plugh
+
+A mysterious recorded voice groans into life and announces:
+   "This exit is closed.  Please leave via main office."
+
+You're at "Y2".
+
+There is a little axe here.
+
+> s
+
+You're in n/s passage above e/w passage.
+
+> d
+
+You are in a dirty broken passage.  To the east is a crawl.  To the
+west is a large passage.  Above you is a hole to another passage.
+
+> w
+
+You're in dusty rock room.
+
+> d
+
+You're at complex junction.
+
+> e
+
+You are in an anteroom leading to a large passage to the east.  Small
+passages go west and up.  The remnants of recent digging are evident.
+A sign in midair here says "Cave under construction beyond this point.
+Proceed at own risk.  [Witt Construction Company]"
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> take magazine
+
+OK
+
+> e
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+> drop magazine
+
+OK
+
+> look
+
+Sorry, but I am not allowed to give more detail.  I will repeat the
+long description of your location.
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> look
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> look
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> look
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> look
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> look
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> look
+
+The sepulchral voice intones, "The cave is now closed."  As the echoes
+fade, there is a blinding flash of light (and a small puff of orange
+smoke). . . .    As your eyes refocus, you look around and find...
+
+You are at the northeast end of an immense room, even larger than the
+Giant Room.  It appears to be a repository for the "Adventure"
+program.  Massive torches far overhead bathe the room with smoky
+yellow light.  Scattered about you can be seen a pile of bottles (all
+of them empty), a nursery of young beanstalks murmuring quietly, a bed
+of oysters, a bundle of black rods with rusty stars on their ends, and
+a collection of brass lanterns.  Off to one side a great many dwarves
+are sleeping on the floor, snoring loudly.  A notice nearby reads: "Do
+not disturb the dwarves!"  An immense mirror is hanging against one
+wall, and stretches to the other end of the room, where various other
+sundry objects can be glimpsed dimly in the distance.
+
+> sw
+
+You are at the southwest end of the repository.  To one side is a pit
+full of fierce green snakes.  On the other side is a row of small
+wicker cages, each of which contains a little sulking bird.  In one
+corner is a bundle of black rods with rusty marks on their ends.  A
+large number of velvet pillows are scattered about on the floor.  A
+vast mirror stretches off to the northeast.  At your feet is a large
+steel grate, next to which is a sign that reads, "Treasure Vault.
+Keys in main office."
+
+The grate is locked.
+
+> take bird
+
+OK
+
+> 
+You scored 391 out of a possible 430, using 345 turns.
+
+Your score puts you in Master Adventurer Class B.
+
+To achieve the next higher rating, you need 20 more points.
diff --git a/tests/takebird.log b/tests/takebird.log
new file mode 100644
index 0000000..557f0ac
--- /dev/null
+++ b/tests/takebird.log
@@ -0,0 +1,353 @@
+## Verify that bird starts caged in endgame
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+no
+seed 1318612053
+e
+plugh
+plove
+get emerald
+w
+drop emerald
+e
+ne
+get pyramid
+s
+plove
+plugh
+drop pyramid
+get lamp
+get water
+plugh
+on
+s
+d
+bedquilt
+w
+e
+take pillow
+w
+oriental
+take vase
+n
+w
+take emerald
+nw
+s
+se
+w
+w
+d
+water plant
+u
+e
+d
+fill bottle
+u
+e
+ne
+e
+u
+e
+u
+n
+plugh
+drop pillow
+drop vase
+drop bottle
+drop emerald
+xyzzy
+take rod
+e
+take cage
+pit
+drop rod
+e
+take bird
+w
+drop bird
+take rod
+wave rod
+take necklace
+drop rod
+take bird
+d
+s
+take nugget
+n
+n
+drop bird
+take bird
+sw
+w
+kill dragon
+yes
+drink blood
+take rug
+e
+e
+n
+take bars
+n
+plugh
+drop cage
+drop necklace
+drop nugget
+drop bars
+drop rug
+xyzzy
+pit
+take rod
+d
+w
+wave rod
+w
+take diamonds
+w
+w
+w
+s
+s
+e
+s
+hit machine
+s
+s
+kill ogre
+n
+take ruby
+s
+w
+n
+n
+sw
+w
+d
+n
+e
+take coins
+e
+s
+take jewelry
+n
+e
+w
+w
+w
+s
+e
+s
+s
+s
+n
+e
+e
+nw
+drop rod
+take jewelry
+take chest
+take ruby
+take diamonds
+take coins
+se
+w
+s
+d
+debris
+xyzzy
+off
+drop coins
+drop diamonds
+drop jewelry
+drop chest
+drop lamp
+take rug
+take emerald
+take cage
+take bottle
+w
+s
+w
+drop bird
+listen
+drop cage
+n
+take appendage
+n
+e
+n
+n
+fill urn
+light urn
+rub urn
+drop rug
+take amber
+drop emerald
+fly
+take sapphire
+fly
+take emerald
+drop ruby
+take rug
+take ruby
+e
+s
+e
+e
+e
+drop emerald
+drop ruby
+drop amber
+drop rug
+drop sapphire
+fill bottle
+take lamp
+plugh
+on
+s
+s
+sw
+w
+n
+reservoir
+n'beh
+n
+n
+u
+u
+u
+u
+u
+ne
+take statuette
+sw
+d
+d
+d
+d
+d
+s
+s
+s
+s
+d
+s
+d
+water plant
+u
+e
+d
+fill bottle
+u
+w
+d
+climb
+w
+take eggs
+n
+oil door
+drop bottle
+n
+take trident
+w
+d
+bedquilt
+e
+n
+open clam
+d
+d
+take pearl
+shell
+s
+u
+e
+u
+n
+plugh
+drop trident
+drop pearl
+drop statuette
+drop appendage
+take keys
+take food
+plugh
+s
+d
+bedquilt
+w
+oriental
+w
+sw
+u
+throw eggs
+ne
+barren
+e
+throw food
+unlock chain
+take chain
+take bear
+fork
+ne
+fee
+fie
+foe
+foo
+e
+take spices
+fork
+w
+w
+sw
+release bear
+sw
+sw
+d
+se
+se
+w
+w
+d
+climb
+w
+take eggs
+n
+n
+w
+d
+bedquilt
+e
+u
+e
+u
+n
+plugh
+drop eggs
+drop chain
+drop spices
+plugh
+s
+look
+look
+n
+plugh
+s
+d
+w
+d
+e
+take magazine
+e
+drop magazine
+look
+look
+look
+look
+look
+look
+look
+sw
+# Good response "OK".
+# Buggy response: "You can catch the bird, but you cannot carry it."
+take bird
diff --git a/tests/tall.chk b/tests/tall.chk
index d962f77..05f456b 100644
--- a/tests/tall.chk
+++ b/tests/tall.chk
@@ -1024,7 +1024,7 @@ seems to open up.
 
 The canyon runs into a mass of boulders -- dead end.
 
-
+> 
 You scored 77 out of a possible 430, using 163 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/tall.log b/tests/tall.log
index 19081c6..1af372e 100644
--- a/tests/tall.log
+++ b/tests/tall.log
@@ -1,4 +1,6 @@
 ## Coverage of LOC_TALL, LOC_WIDEPLACE, LOC_TIGHTPLACE
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
@@ -164,4 +166,4 @@ e
 s
 n
 n
-w
\ No newline at end of file
+w
diff --git a/tests/tapdiffer b/tests/tapdiffer
index b529a39..495427e 100755
--- a/tests/tapdiffer
+++ b/tests/tapdiffer
@@ -1,4 +1,6 @@
 #! /bin/sh
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: MIT-0
 #
 # tapdiffer - Render diff between input and checkfile as a TAP report
 #
@@ -8,15 +10,32 @@
 # A nonempty diff is shipped as a TAP YAML block following "not ok" 
 # unless QUIET=1 in the environment.
 #
+# This code is intended to be embedded in your project. The author
+# grants permission for it to be distributed under the prevailing
+# license of your project if you choose, provided that license is
+# OSD-compliant; otherwise the following SPDX tag incorporates the
+# MIT No Attribution license by reference.
+#
+# A newer version may be available at https://gitlab.com/esr/tapview
+# Check your last commit dqte for this file against the commit list
+# there to see if it might be a good idea to update.
+#
+if [ "$1" = "-b" ]
+then
+    diffopts=-ub
+    shift
+else
+    diffopts=-u
+fi
+
 legend=$1
 checkfile=$2
 
 trap 'rm /tmp/tapdiff$$' EXIT HUP INT QUIT TERM
 
-if diff --text -u ${checkfile} - >/tmp/tapdiff$$
+if diff --text "${diffopts}" "${checkfile}" - >/tmp/tapdiff$$
 then
 	echo "ok - ${legend}"
-	exit 0
 else
 	echo "not ok - ${checkfile}: ${legend}"
 	if [ ! "${QUIET}" = 1 ]
@@ -25,7 +44,6 @@ else
 		sed </tmp/tapdiff$$ -e 's/^/  /'
 		echo "  ..."
 	fi
-	exit 1
 fi
 
 # end
diff --git a/tests/tapview b/tests/tapview
index 9acd0c4..33216ad 100755
--- a/tests/tapview
+++ b/tests/tapview
@@ -1,33 +1,18 @@
 #! /bin/sh
 # tapview - a TAP (Test Anything Protocol) viewer in pure POSIX shell
 #
-# Copyright by Eric S. Raymond
-#
 # This code is intended to be embedded in your project. The author
 # grants permission for it to be distributed under the prevailing
 # license of your project if you choose, provided that license is
-# OSD-compliant; otherwise the following SPDX tag applies.
+# OSD-compliant; otherwise the following SPDX tag incorporates a
+# license by reference.
 #
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
 # SPDX-License-Identifier: BSD-2-Clause
 #
-# This is version 1.0
+# This is version 1.6
 # A newer version may be available at https://gitlab.com/esr/tapview
 #
-# POSIX allows but does not mandate that -n suppresses emission of a
-# trailing newline in echo. Thus, some shell builtin echos don't do
-# that.  Cope gracefully.
-# shellcheck disable=SC2039
-if [ "$(echo -n "a"; echo "b")" != "ab" ]
-then
-    ECHO="echo"
-elif [ "$(/bin/echo -n "a"; /bin/echo "b")" = "ab" ]
-then
-    ECHO="/bin/echo"
-else
-    echo "tapview: bailing out, your echo lacks -n support."
-    exit 3
-fi
-
 OK="."
 FAIL="F"
 SKIP="s"
@@ -36,44 +21,94 @@ TODO_OK="u"
 
 ship_char() {
     # shellcheck disable=SC2039
-    "${ECHO}" -n "$1"
+    printf '%s' "$1"	# https://www.etalabs.net/sh_tricks.html
 }
 
 ship_line() {
     report="${report}${1}\n"
 }
 
+ship_error() {
+    # Terminate dot display and bail out with error
+    if [ "${testcount}" -gt 0 ]
+    then
+	echo ""
+    fi
+    report="${report}${1}\n"
+    echo "${report}"
+    exit 1
+}
+
 testcount=0
 failcount=0
 skipcount=0
 todocount=0
-test_before_plan=no
-test_after_plan=no
-expect=""
 status=0
-
 report=""
 IFS=""
-state=start
+ln=0
+state=plaintext
+
+# shellcheck disable=SC2086
+context_get () { printenv "ctx_${1}${depth}"; }
+context_set () { export "ctx_${1}${depth}=${2}"; }
+
+context_push () {
+    context_set plan ""
+    context_set count 0
+    context_set test_before_plan no
+    context_set test_after_plan no
+    context_set expect ""
+    context_set bail no
+    context_set strict no
+}
+
+context_pop () {
+    if [ "$(context_get count)" -gt 0 ] && [ -z "$(context_get plan)" ]
+    then
+	ship_line "Missing a plan at line ${ln}."
+	status=1
+    elif [ "$(context_get test_before_plan)" = "yes" ] && [ "$(context_get test_after_plan)" = "yes" ] 
+    then
+	ship_line "A plan line may only be placed before or after all tests."
+	status=1
+    elif [ "$(context_get plan)" != "" ] && [ "$(context_get expect)" -gt "$(context_get count)" ]
+    then
+	ship_line "Expected $(context_get expect) tests but only ${testcount} ran."
+	status=1
+    fi
+}
+
+depth=0
+context_push
+
 while read -r line
 do
+    ln=$((ln + 1))
+    # Process bailout
     if expr "$line" : "Bail out!" >/dev/null
     then
 	ship_line "$line"
 	status=2
 	break
     fi
-    if expr "$line" : '1\.\.[0-9][0-9]*' >/dev/null >/dev/null
+    # Use the current indent to choose a scope level
+    indent=$(expr "$line" : '[ 	]*')
+    if [ "${indent}" -lt "${depth}" ]
+    then
+	context_pop
+        depth="${indent}"
+    elif [ "${indent}" -gt "${depth}" ]
+    then
+	depth="${indent}"
+	context_push
+    fi
+    # Process a plan line
+    if expr "$line" : '[ 	]*1\.\.[0-9][0-9]*' >/dev/null
     then
-	if [ "$expect" != "" ]
+	if [ "$(context_get plan)" != "" ]
 	then
-	    if [ "${testcount}" -gt 0 ]
-	    then
-		echo ""
-	    fi
-	    ship_line "Cannot have more than one plan line."
-	    echo "${report}"
-	    exit 1
+	    ship_error "tapview: cannot have more than one plan line."
 	fi
 	if expr "$line" : ".* *SKIP" >/dev/null || expr "$line" : ".* *skip" >/dev/null
 	then
@@ -81,62 +116,114 @@ do
 	    echo "${report}"
 	    exit 1	# Not specified in the standard whether this should exit 1 or 0
 	fi
-	expect=$(expr "$line" : '1\.\.\([0-9][0-9]*\)')
+	context_set plan "${line}"
+	context_set expect "$(expr "$line" : '[ 	]*1\.\.\([0-9][0-9]*\)')"
 	continue
+    elif expr "$line" : '[ 	]*[0-9][0-9]*\.\.[0-9][0-9]*' >/dev/null
+    then
+	 echo "Ill-formed plan line at ${ln}"
+	 exit 1
+    fi
+    # Check for out-of-order test point numbers with the sequence (TAP 14)
+    testpoint=$(expr "$line" : '.*ok  *\([0-9][0-9]*\)')
+    if [ "${testpoint}" != "" ] && [ "$(context_get expect)" != "" ] && [ "${testpoint}" -gt "$(context_get expect)" ]
+    then
+	ship_error "tapview: testpoint number ${testpoint} is out of range for plan $(context_get plan)."
     fi
-    if expr "$line" : "ok" >/dev/null
+    # Process an ok line
+    if expr "$line" : "[ 	]*ok" >/dev/null
     then
+	context_set count $(($(context_get count) + 1)) 
 	testcount=$((testcount + 1))
-	if [ "$expect" = "" ]
+	if [ "$(context_get plan)" = "" ]
 	then
-	    test_before_plan=yes
+	    context_set test_before_plan yes
 	else
-	    test_after_plan=yes
+	    context_set test_after_plan yes
 	fi
-	if expr "$line" : ".*# *TODO" >/dev/null || expr "$line" : ".*# *todo" >/dev/null
+	if expr "$line" : "[^#]* # *TODO" >/dev/null || expr "$line" : "[^#]* # *todo" >/dev/null
 	then
 	    ship_char ${TODO_OK}
 	    ship_line "$line"
 	    todocount=$((todocount + 1))
-	elif expr "$line" : ".*# *SKIP" >/dev/null || expr "$line" : ".*# *skip" >/dev/null
+	    if expr "$line" : "[^#]*#[^ ]" >/dev/null
+	    then
+		ship_line "Suspicious comment leader at ${ln}"
+	    fi
+	elif expr "$line" : "[^#]* # *SKIP" >/dev/null || expr "$line" : "[^#]* # *skip" >/dev/null
 	then
 	    ship_char ${SKIP}
 	    ship_line "$line"
 	    skipcount=$((skipcount + 1))
+	    if expr "$line" : "[^#]*#[^ ]" >/dev/null
+	    then
+		ship_line "Suspicious comment leader at ${ln}"
+	    fi
 	else
 	    ship_char ${OK}
 	fi
-	state=ok
+	state=plaintext
 	continue
     fi
-    if expr "$line" : "not ok" >/dev/null
+    # Process a not-ok line
+    if expr "$line" : "[ 	]*not ok" >/dev/null
     then
+	context_set count $(($(context_get count) + 1)) 
 	testcount=$((testcount + 1))
-	if [ "$expect" = "" ]
+	if [ "$(context_get plan)" = "" ]
 	then
-	    test_before_plan=yes
+	    context_set test_before_plan yes
 	else
-	    test_after_plan=yes
+	    context_set test_after_plan yes
 	fi
-	if expr "$line" : ".*# *SKIP" >/dev/null || expr "$line" : ".*# *skip" >/dev/null
+	if expr "$line" : "[^#]* # *SKIP" >/dev/null || expr "$line" : "[^#]* # *skip" >/dev/null
 	then
 	    ship_char "${SKIP}"
-	    state=ok
+	    state=plaintext
 	    skipcount=$((skipcount + 1))
+	    if expr "$line" : "[^#]* #[^ ]" >/dev/null
+	    then
+		ship_line "Suspicious comment leader at lime ${ln}"
+	    fi
 	    continue
 	fi
-	if expr "$line" : ".*# *TODO" >/dev/null || expr "$line" : ".*# *todo" >/dev/null
+	if expr "$line" : "[^#]* # *TODO" >/dev/null || expr "$line" : "[^#]* # *todo" >/dev/null
 	then
 	    ship_char ${TODO_NOT_OK}
-	    state=ok
+	    state=plaintext
 	    todocount=$((todocount + 1))
+	    if expr "$line" : "[^#]* #[^ ]" >/dev/null
+	    then
+		ship_line "Suspicious comment leader at line ${ln}"
+	    fi
 	    continue
 	fi
 	ship_char "${FAIL}"
 	ship_line "$line"
-	state=not_ok
+	state=plaintext
 	failcount=$((failcount + 1))
 	status=1
+	if [ "$(context_get bail)" = yes ]
+	then
+	    ship_line "Bailing out on line ${ln} due to +bail pragma."
+	    break
+	fi
+	continue
+    fi
+    # Process a TAP 14 pragma
+    if expr "$line" : "pragma" >/dev/null
+    then
+	unset IFS
+	# shellcheck disable=SC2086
+	set -- $line
+	case "$2" in
+	    +bail) context_set bail yes;;
+	    -bail) context_set bail yes;;
+	    +strict) context_set strict yes;;
+	    -strict) context_set strict yes;;
+	    *) ship_line "Pragma '$line' ignored";;
+	esac
+	IFS=""
 	continue
     fi
     # shellcheck disable=SC2166
@@ -145,34 +232,35 @@ do
 	ship_line "$line"
 	if expr "$line" : '[ 	]*\.\.\.' >/dev/null
 	then
-	    state=ok
+	    state=plaintext
+	else
+	    continue
 	fi
     elif expr "$line" : "[ 	]*---" >/dev/null
     then
 	ship_line "$line"
 	state=yaml
+	continue
+    fi
+    # Ignore blank lines and comments
+    if [ -z "$line" ] || expr "$line" : '[ 	]+$' >/dev/null || expr "$line" : "#" >/dev/null
+    then
+	continue
+    fi
+    # Any line that is not a valid plan, test result, pragma,
+    # or comment lands here.
+    if [ "$(context_get strict)" = yes ]
+    then
+	ship_line "Bailing out on line ${ln} due to +strict pragma"
+	status=1
+	break
     fi
 done
 
 /bin/echo ""
 
-if [ -z "$expect" ]
-then
-    ship_line "Missing a plan."
-    status=1
-elif [ "$test_before_plan" = "yes" ] && [ "$test_after_plan" = "yes" ] 
-then
-    ship_line "A plan line may only be placed before or after all tests."
-    status=1
-elif [ "${expect}" -gt "${testcount}" ]
-then
-    ship_line "Expected ${expect} tests but only ${testcount} ran."
-    status=1
-elif [ "${expect}" -lt "${testcount}" ]
-then
-    ship_line "Expected ${expect} tests but ${testcount} ran."
-    status=1
-fi
+depth=0
+context_pop
 
 report="${report}${testcount} tests, ${failcount} failures"
 if [ "$todocount" != 0 ]
diff --git a/tests/trident.chk b/tests/trident.chk
index 37de9fe..c27ef42 100644
--- a/tests/trident.chk
+++ b/tests/trident.chk
@@ -1420,7 +1420,7 @@ Your lamp is now on.
 
 You're at "Y2".
 
-
+> 
 You scored 167 out of a possible 430, using 231 turns.
 
 You have achieved the rating: "Experienced Adventurer".
diff --git a/tests/trident.log b/tests/trident.log
index 871834a..bca7e3c 100644
--- a/tests/trident.log
+++ b/tests/trident.log
@@ -1,4 +1,6 @@
 ## 161-point run to pirate appearance and death by dwarf
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56
 n
 seed 1071883378
diff --git a/tests/troll_returns.chk b/tests/troll_returns.chk
index b4d7c2e..6715126 100644
--- a/tests/troll_returns.chk
+++ b/tests/troll_returns.chk
@@ -748,7 +748,7 @@ There is a huge beanstalk growing out of the west pit up to the hole.
 You are at the bottom of the eastern pit in the Twopit Room.  There is
 a small pool of oil in one corner of the pit.
 
-> g oil
+> get oil
 
 Your bottle is now full of oil.
 
@@ -803,7 +803,7 @@ You're in Giant Room.
 
 There is a large nest here, full of golden eggs!
 
-> g
+> take
 
 OK
 
@@ -912,7 +912,7 @@ mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
 A burly troll stands by the bridge and insists you throw him a
 treasure before you may cross.
 
-
+> 
 You scored 75 out of a possible 430, using 140 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/troll_returns.log b/tests/troll_returns.log
index 2b93a30..2cbf136 100644
--- a/tests/troll_returns.log
+++ b/tests/troll_returns.log
@@ -1,4 +1,6 @@
 ## See that troll returns if we stole his eggs before crossing
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
@@ -119,7 +121,7 @@ water plant
 u
 e
 d
-g oil
+get oil
 u
 w
 d
@@ -128,7 +130,7 @@ w
 n
 oil door
 s
-g
+take
 n
 n
 w
diff --git a/tests/turnpenalties.log b/tests/turnpenalties.log
index 2cd3c9e..e4d2df9 100644
--- a/tests/turnpenalties.log
+++ b/tests/turnpenalties.log
@@ -1,4 +1,6 @@
 ## check that the turn count penalties occur
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1951269982
 in
diff --git a/tests/urntest.chk b/tests/urntest.chk
index 0ca8748..8724f9d 100644
--- a/tests/urntest.chk
+++ b/tests/urntest.chk
@@ -2105,7 +2105,7 @@ A small urn full of oil is embedded in the rock.
 If you mean to use the Persian rug, it does not appear inclined to
 cooperate.
 
-
+> 
 You scored 265 out of a possible 430, using 358 turns.
 
 You have reached "Junior Master" status.
diff --git a/tests/urntest.log b/tests/urntest.log
index a02d663..b67e61c 100644
--- a/tests/urntest.log
+++ b/tests/urntest.log
@@ -1,4 +1,6 @@
 ## Test verbs on urn
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
diff --git a/tests/urntest2.chk b/tests/urntest2.chk
index 25de76b..8f8e9cc 100644
--- a/tests/urntest2.chk
+++ b/tests/urntest2.chk
@@ -2030,7 +2030,7 @@ There is nothing here with which to fill it.
 
 The urn is now dark.
 
-
+> 
 You scored 267 out of a possible 430, using 344 turns.
 
 You have reached "Junior Master" status.
diff --git a/tests/urntest2.log b/tests/urntest2.log
index e0c3a6b..0bcbd7e 100644
--- a/tests/urntest2.log
+++ b/tests/urntest2.log
@@ -1,4 +1,6 @@
 ## Test filling urn when you have no bottle
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # Also, try to lock door after oiling it
 n
 seed 1838473132
diff --git a/tests/urntest3.chk b/tests/urntest3.chk
index 1c95ae3..34c30e7 100644
--- a/tests/urntest3.chk
+++ b/tests/urntest3.chk
@@ -2015,7 +2015,7 @@ You are wandering aimlessly through the forest.
 
 There is nothing here with which to fill the bottle.
 
-
+> 
 You scored 267 out of a possible 430, using 340 turns.
 
 You have reached "Junior Master" status.
diff --git a/tests/urntest3.log b/tests/urntest3.log
index a835588..0ec5aab 100644
--- a/tests/urntest3.log
+++ b/tests/urntest3.log
@@ -1,4 +1,6 @@
 ## Test filling urn twice. Also, try to lock door after oiling it.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
diff --git a/tests/vending.chk b/tests/vending.chk
index 6e67b28..4f837bc 100644
--- a/tests/vending.chk
+++ b/tests/vending.chk
@@ -305,7 +305,7 @@ Attack what?
 
 The vending machine swings back to block the passage.
 
-
+> 
 You scored 75 out of a possible 430, using 56 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/vending.log b/tests/vending.log
index 883a3c7..7e33036 100644
--- a/tests/vending.log
+++ b/tests/vending.log
@@ -1,4 +1,6 @@
 ## Get batteries from the vending machine
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1635997320
 in
diff --git a/tests/wakedwarves.log b/tests/wakedwarves.log
index d733fb9..2ed3948 100644
--- a/tests/wakedwarves.log
+++ b/tests/wakedwarves.log
@@ -1,4 +1,6 @@
 ## Wake the dwarves and die.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
diff --git a/tests/wakedwarves2.log b/tests/wakedwarves2.log
index adf737e..d6f91d2 100644
--- a/tests/wakedwarves2.log
+++ b/tests/wakedwarves2.log
@@ -1,4 +1,6 @@
 ## Wake the dwarves by waving rod and die.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
diff --git a/tests/wakedwarves3.log b/tests/wakedwarves3.log
index e04669b..2cbd78e 100644
--- a/tests/wakedwarves3.log
+++ b/tests/wakedwarves3.log
@@ -1,4 +1,6 @@
 ## Wake the dwarves by attacking one and die.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1838473132
 in
diff --git a/tests/water_plant2.chk b/tests/water_plant2.chk
index 1cbf119..9ec91c8 100644
--- a/tests/water_plant2.chk
+++ b/tests/water_plant2.chk
@@ -392,14 +392,6 @@ You are in the south side chamber.
 
 There is precious jewelry here!
 
->  
-
-I don't know how to apply that word here.
-
-You are in the south side chamber.
-
-There is precious jewelry here!
-
 > s
 
 There is no way to go that direction.
@@ -448,8 +440,6 @@ There are bars of silver here!
 
 You're at "Y2".
 
-A hollow voice says "PLUGH".
-
 There is a little axe here.
 
 > d
@@ -556,8 +546,6 @@ Your bottle is now full of water.
 
 > s
 
-There is a threatening little dwarf in the room with you!
-
 You are in a north/south canyon about 25 feet across.  The floor is
 covered by white mist seeping in from the north.  The walls extend
 upward for well over 100 feet.  Suspended from some unseen point far
@@ -568,42 +556,62 @@ small window can be seen in either wall, some fifty feet up.
 
 > s
 
-A little dwarf with a big knife blocks your way.
-
 There is a threatening little dwarf in the room with you!
 
 One sharp nasty knife is thrown at you!
 
 It misses!
 
-You're in Mirror Canyon.
+You are in a secret n/s canyon above a large room.
 
 > s
 
 There is a threatening little dwarf in the room with you!
 
-You are in a secret n/s canyon above a large room.
+You are in a secret canyon which exits to the north and east.
+
+There is a Persian rug spread out on the floor!
+
+The blood-specked body of a huge green dead dragon lies to one side.
 
 > d
 
+There is no way to go that direction.
+
 There is a threatening little dwarf in the room with you!
 
-You're in Slab Room.
+One sharp nasty knife is thrown at you!
+
+It misses!
+
+You are in a secret canyon which exits to the north and east.
+
+There is a Persian rug spread out on the floor!
+
+The blood-specked body of a huge green dead dragon lies to one side.
 
 > s
 
+There is no way to go that direction.
+
 There is a threatening little dwarf in the room with you!
 
-You're at west end of Twopit Room.
+One sharp nasty knife is thrown at you!
 
-The top of a 12-foot-tall beanstalk is poking out of the west pit.
+It misses!
+
+You are in a secret canyon which exits to the north and east.
+
+There is a Persian rug spread out on the floor!
+
+The blood-specked body of a huge green dead dragon lies to one side.
 
 > water plant
 
 What do you want to do with the water?
 
-
-You scored 65 out of a possible 430, using 85 turns.
+> 
+You scored 65 out of a possible 430, using 84 turns.
 
 Your score qualifies you as a novice class adventurer.
 
diff --git a/tests/water_plant2.log b/tests/water_plant2.log
index 0136f1e..4a6f489 100644
--- a/tests/water_plant2.log
+++ b/tests/water_plant2.log
@@ -1,4 +1,7 @@
 ## Check that pour correctly switches among plant states (fuzzed)
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE Behavior differs due to a parser bug fix.
 n
 seed 183847312
 in
@@ -56,7 +59,6 @@ s
 s
 u
 w
- 
 s
 w
 s
diff --git a/tests/weirdbird.chk b/tests/weirdbird.chk
index 52f5eb7..c583787 100644
--- a/tests/weirdbird.chk
+++ b/tests/weirdbird.chk
@@ -218,7 +218,7 @@ You're outside grate.
 
 The grate is open.
 
-
+> 
 You scored 30 out of a possible 430, using 37 turns.
 
 You are obviously a rank amateur.  Better luck next time.
diff --git a/tests/weirdbird.log b/tests/weirdbird.log
index 78ae7de..5c48271 100644
--- a/tests/weirdbird.log
+++ b/tests/weirdbird.log
@@ -1,4 +1,6 @@
 ## Do pointless things to the bird to test odd cases.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 694608006
 in
@@ -36,7 +38,7 @@ take bird
 get rod
 wave rod
 attack bird
-# Also, test grare as a motion verb.
+# Also, test grate as a motion verb.
 grate
 up
 n
diff --git a/tests/weirddwarf.chk b/tests/weirddwarf.chk
index 1d73e0e..0216bc5 100644
--- a/tests/weirddwarf.chk
+++ b/tests/weirddwarf.chk
@@ -514,7 +514,7 @@ With what?  Your bare hands?
 
 Feed what?
 
-
+> 
 You scored 103 out of a possible 430, using 88 turns.
 
 Your score qualifies you as a novice class adventurer.
diff --git a/tests/weirddwarf.log b/tests/weirddwarf.log
index b7af3a0..a857eb0 100644
--- a/tests/weirddwarf.log
+++ b/tests/weirddwarf.log
@@ -1,4 +1,6 @@
 ## Exercise various verbs on a dwarf
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 n
 seed 1071883378
 in
diff --git a/tests/win430.chk b/tests/win430.chk
new file mode 100644
index 0000000..0a7e9c8
--- /dev/null
+++ b/tests/win430.chk
@@ -0,0 +1,2108 @@
+
+Welcome to Adventure!!  Would you like instructions?
+
+> no
+
+You are standing at the end of a road before a small brick building.
+Around you is a forest.  A small stream flows out of the building and
+down a gully.
+
+> seed 1318612053
+
+Seed set to 1318612053
+
+You're in front of building.
+
+> e
+
+You are inside a building, a well house for a large spring.
+
+There are some keys on the ground here.
+
+There is a shiny brass lamp nearby.
+
+There is food here.
+
+There is a bottle of water here.
+
+> plugh
+
+>>Foof!<<
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> plove
+
+>>Foof!<<
+
+You're in a small chamber lit by an eerie green light.  An extremely
+narrow tunnel exits to the west.  A dark corridor leads ne.
+
+There is an emerald here the size of a plover's egg!
+
+> get emerald
+
+OK
+
+> w
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> drop emerald
+
+OK
+
+> e
+
+You're in Plover Room.
+
+> ne
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> get pyramid
+
+OK
+
+> s
+
+You're in Plover Room.
+
+> plove
+
+>>Foof!<<
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> plugh
+
+>>Foof!<<
+
+You're inside building.
+
+There are some keys on the ground here.
+
+There is a shiny brass lamp nearby.
+
+There is food here.
+
+There is a bottle of water here.
+
+> drop pyramid
+
+OK
+
+> get lamp
+
+OK
+
+> get water
+
+OK
+
+> plugh
+
+>>Foof!<<
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> on
+
+Your lamp is now on.
+
+You are in a large room, with a passage to the south, a passage to the
+west, and a wall of broken rock to the east.  There is a large "Y2" on
+a rock in the room's center.
+
+A hollow voice says "PLUGH".
+
+> s
+
+You are in a low n/s passage at a hole in the floor.  The hole goes
+down to an e/w passage.
+
+There are bars of silver here!
+
+> d
+
+You are in a dirty broken passage.  To the east is a crawl.  To the
+west is a large passage.  Above you is a hole to another passage.
+
+> bedquilt
+
+You are in Bedquilt, a long east/west passage with holes everywhere.
+To explore at random select north, south, up, or down.
+
+> w
+
+You are in a room whose walls resemble Swiss cheese.  Obvious passages
+go west, east, ne, and nw.  Part of the room is occupied by a large
+bedrock block.
+
+> e
+
+You are in the Soft Room.  The walls are covered with heavy curtains,
+the floor with a thick pile carpet.  Moss covers the ceiling.
+
+A small velvet pillow lies on the floor.
+
+> take pillow
+
+OK
+
+> w
+
+You're in Swiss Cheese Room.
+
+> oriental
+
+This is the Oriental Room.  Ancient oriental cave drawings cover the
+walls.  A gently sloping passage leads upward to the north, another
+passage leads se, and a hands and knees crawl leads west.
+
+There is a delicate, precious, ming vase here!
+
+> take vase
+
+OK
+
+> n
+
+You are following a wide path around the outer edge of a large cavern.
+Far below, through a heavy white mist, strange splashing noises can be
+heard.  The mist rises up through a fissure in the ceiling.  The path
+exits to the south and west.
+
+> w
+
+You are in an alcove.  A small nw path seems to widen after a short
+distance.  An extremely tight tunnel leads east.  It looks like a very
+tight squeeze.  An eerie light can be seen at the other end.
+
+There is an emerald here the size of a plover's egg!
+
+> take emerald
+
+OK
+
+> nw
+
+You're in misty cavern.
+
+> s
+
+You're in Oriental Room.
+
+> se
+
+You're in Swiss Cheese Room.
+
+> w
+
+You are at the east end of the Twopit Room.  The floor here is
+littered with thin rock slabs, which make it easy to descend the pits.
+There is a path here bypassing the pits to connect passages from east
+and west.  There are holes all over, but the only big one is on the
+wall directly over the west pit where you can't get to it.
+
+> w
+
+You are at the west end of the Twopit Room.  There is a large hole in
+the wall above the pit at this end of the room.
+
+> d
+
+You are at the bottom of the western pit in the Twopit Room.  There is
+a large hole in the wall about 25 feet above you.
+
+There is a tiny little plant in the pit, murmuring "water, water, ..."
+
+> water plant
+
+The plant spurts into furious growth for a few seconds.
+
+You're in west pit.
+
+There is a 12-foot-tall beanstalk stretching up out of the pit,
+bellowing "WATER!! WATER!!"
+
+> u
+
+You're at west end of Twopit Room.
+
+The top of a 12-foot-tall beanstalk is poking out of the west pit.
+
+> e
+
+You're at east end of Twopit Room.
+
+The top of a 12-foot-tall beanstalk is poking out of the west pit.
+
+> d
+
+You are at the bottom of the eastern pit in the Twopit Room.  There is
+a small pool of oil in one corner of the pit.
+
+> fill bottle
+
+Your bottle is now full of oil.
+
+> u
+
+You're at east end of Twopit Room.
+
+The top of a 12-foot-tall beanstalk is poking out of the west pit.
+
+> e
+
+You're in Swiss Cheese Room.
+
+> ne
+
+You're in Bedquilt.
+
+> e
+
+You are at a complex junction.  A low hands and knees passage from the
+north joins a higher crawl from the east to make a walking passage
+going west.  There is also a large room above.  The air is damp here.
+
+> u
+
+You are in a large room full of dusty rocks.  There is a big hole in
+the floor.  There are cracks everywhere, and a passage leading east.
+
+> e
+
+You're in dirty passage.
+
+> u
+
+You're in n/s passage above e/w passage.
+
+There are bars of silver here!
+
+> n
+
+A little dwarf just walked around a corner, saw you, threw a little
+axe at you which missed, cursed, and ran away.
+
+You're at "Y2".
+
+There is a little axe here.
+
+> plugh
+
+>>Foof!<<
+
+You're inside building.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+There are some keys on the ground here.
+
+There is food here.
+
+> drop pillow
+
+OK
+
+> drop vase
+
+The vase is now resting, delicately, on a velvet pillow.
+
+> drop bottle
+
+OK
+
+> drop emerald
+
+OK
+
+> xyzzy
+
+>>Foof!<<
+
+You are in a debris room filled with stuff washed in from the surface.
+A low wide passage with cobbles becomes plugged with mud and debris
+here, but an awkward canyon leads upward and west.  In the mud someone
+has scrawled, "MAGIC WORD XYZZY".
+
+A three foot black rod with a rusty star on an end lies nearby.
+
+> take rod
+
+OK
+
+> e
+
+You are crawling over cobbles in a low passage.  There is a dim light
+at the east end of the passage.
+
+There is a small wicker cage discarded nearby.
+
+> take cage
+
+OK
+
+> pit
+
+At your feet is a small pit breathing traces of white mist.  An east
+passage ends here except for a small crack leading on.
+
+Rough stone steps lead down the pit.
+
+> drop rod
+
+OK
+
+> e
+
+You are in a splendid chamber thirty feet high.  The walls are frozen
+rivers of orange stone.  An awkward canyon and a good passage exit
+from east and west sides of the chamber.
+
+A cheerful little bird is sitting here singing.
+
+> take bird
+
+OK
+
+> w
+
+You're at top of small pit.
+
+A three foot black rod with a rusty star on an end lies nearby.
+
+Rough stone steps lead down the pit.
+
+> drop bird
+
+OK
+
+> take rod
+
+OK
+
+> wave rod
+
+The bird flies about agitatedly for a moment, then disappears through
+the crack.  It reappears shortly, carrying in its beak a jade
+necklace, which it drops at your feet.
+
+> take necklace
+
+OK
+
+> drop rod
+
+OK
+
+> take bird
+
+OK
+
+> d
+
+You are at one end of a vast hall stretching forward out of sight to
+the west.  There are openings to either side.  Nearby, a wide stone
+staircase leads downward.  The hall is filled with wisps of white mist
+swaying to and fro almost as if alive.  A cold wind blows up the
+staircase.  There is a passage at the top of a dome behind you.
+
+Rough stone steps lead up the dome.
+
+> s
+
+This is a low room with a crude note on the wall.  The note says,
+"You won't get it up the steps".
+
+There is a large sparkling nugget of gold here!
+
+> take nugget
+
+OK
+
+> n
+
+You're in Hall of Mists.
+
+> n
+
+You are in the Hall of the Mountain King, with passages off in all
+directions.
+
+A huge green fierce snake bars the way!
+
+> drop bird
+
+The little bird attacks the green snake, and in an astounding flurry
+drives the snake away.
+
+> take bird
+
+OK
+
+> sw
+
+You are in a secret canyon which here runs e/w.  It crosses over a
+very tight canyon 15 feet below.  If you go down you may not be able
+to get back up.
+
+> w
+
+You are in a secret canyon which exits to the north and east.
+
+A huge green fierce dragon bars the way!
+
+The dragon is sprawled out on a Persian rug!!
+
+> kill dragon
+
+With what?  Your bare hands?
+
+> yes
+
+Congratulations!  You have just vanquished a dragon with your bare
+hands!  (Unbelievable, isn't it?)
+
+You are in a secret canyon which exits to the north and east.
+
+There is a Persian rug spread out on the floor!
+
+The blood-specked body of a huge green dead dragon lies to one side.
+
+> drink blood
+
+Your head buzzes strangely for a moment.
+
+> take rug
+
+OK
+
+> e
+
+You're in secret e/w canyon above tight canyon.
+
+> e
+
+You're in Hall of Mt King.
+
+> n
+
+You're in n/s passage above e/w passage.
+
+There are bars of silver here!
+
+> take bars
+
+OK
+
+> n
+
+You're at "Y2".
+
+There is a little axe here.
+
+> plugh
+
+>>Foof!<<
+
+You're inside building.
+
+There is an emerald here the size of a plover's egg!
+
+There is a bottle of oil here.
+
+There is a delicate, precious, ming vase here!
+
+A small velvet pillow lies on the floor.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+There are some keys on the ground here.
+
+There is food here.
+
+> drop cage
+
+OK
+
+> drop necklace
+
+OK
+
+> drop nugget
+
+OK
+
+> drop bars
+
+OK
+
+> drop rug
+
+OK
+
+> xyzzy
+
+>>Foof!<<
+
+You're in debris room.
+
+> pit
+
+You're at top of small pit.
+
+A three foot black rod with a rusty star on an end lies nearby.
+
+Rough stone steps lead down the pit.
+
+> take rod
+
+OK
+
+> d
+
+You're in Hall of Mists.
+
+Rough stone steps lead up the dome.
+
+> w
+
+You are on the east bank of a fissure slicing clear across the hall.
+The mist is quite thick here, and the fissure is too wide to jump.
+
+> wave rod
+
+A crystal bridge now spans the fissure.
+
+> w
+
+You are on the west side of the fissure in the Hall of Mists.
+
+There are diamonds here!
+
+A crystal bridge spans the fissure.
+
+> take diamonds
+
+OK
+
+> w
+
+There is a threatening little dwarf in the room with you!
+
+You are at the west end of the Hall of Mists.  A low wide crawl
+continues west and another goes north.  To the south is a little
+passage 6 feet off the floor.
+
+> w
+
+There is a threatening little dwarf in the room with you!
+
+You are at the east end of a very long hall apparently without side
+chambers.  To the east a low wide crawl slants up.  To the north a
+round two foot hole slants down.
+
+> w
+
+There is a threatening little dwarf in the room with you!
+
+You are at the west end of a very long featureless hall.  The hall
+joins up with a narrow north/south passage.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+You are in a maze of twisty little passages, all different.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+You are in a maze of twisting little passages, all different.
+
+> e
+
+There is a threatening little dwarf in the room with you!
+
+You are in a little maze of twisting passages, all different.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+Dead end
+
+There is a massive and somewhat battered vending machine here.  The
+instructions on it read: "Drop coins here to receive fresh batteries."
+
+> hit machine
+
+As you strike the vending machine, it pivots backward along with a
+section of wall, revealing a dark passage leading south.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+You are in a long, rough-hewn, north/south corridor.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+You are in a large chamber with passages to the west and north.
+
+A formidable ogre bars the northern exit.
+
+> kill ogre
+
+The ogre, who despite his bulk is quite agile, easily dodges your
+attack.  He seems almost amused by your puny effort.
+
+One sharp nasty knife is thrown at you!
+
+The ogre, distracted by your rush, is struck by the knife.  With a
+blood-curdling yell he turns and bounds after the dwarf, who flees
+in panic.  You are left alone in the room.
+
+> n
+
+You are in the ogre's storeroom.  The only exit is to the south.
+
+There is an enormous ruby here!
+
+> take ruby
+
+OK
+
+> s
+
+You are in a large chamber with passages to the west and north.
+
+> w
+
+You are in a long, rough-hewn, north/south corridor.
+
+> n
+
+Dead end
+
+There is a massive vending machine here, swung back to reveal a
+southward passage.
+
+> n
+
+You are in a little maze of twisting passages, all different.
+
+> sw
+
+You are in a maze of twisting little passages, all different.
+
+> w
+
+You are in a maze of twisty little passages, all different.
+
+> d
+
+You're at west end of long hall.
+
+> n
+
+You are at a crossover of a high n/s passage and a low e/w one.
+
+> e
+
+You are in the west side chamber of the Hall of the Mountain King.
+A passage continues west and up here.
+
+There are many coins here!
+
+> take coins
+
+OK
+
+> e
+
+You're in Hall of Mt King.
+
+> s
+
+You are in the south side chamber.
+
+There is precious jewelry here!
+
+> take jewelry
+
+OK
+
+> n
+
+You're in Hall of Mt King.
+
+> e
+
+You're in Hall of Mists.
+
+Rough stone steps lead up the dome.
+
+> w
+
+You're on east bank of fissure.
+
+A crystal bridge spans the fissure.
+
+> w
+
+You're on west bank of fissure.
+
+A crystal bridge spans the fissure.
+
+> w
+
+You're at west end of Hall of Mists.
+
+> s
+
+You are in a maze of twisty little passages, all alike.
+
+> e
+
+Out from the shadows behind you pounces a bearded pirate!  "Har, har,"
+he chortles, "I'll just take all this booty and hide it away with me
+chest deep in the maze!"  He snatches your treasure and vanishes into
+the gloom.
+
+You are in a maze of twisty little passages, all alike.
+
+> s
+
+You are in a maze of twisty little passages, all alike.
+
+> s
+
+You are in a maze of twisty little passages, all alike.
+
+> s
+
+You are in a maze of twisty little passages, all alike.
+
+> n
+
+You are in a maze of twisty little passages, all alike.
+
+> e
+
+You are on the brink of a thirty foot pit with a massive orange column
+down one wall.  You could climb down here but you could not get back
+up.  The maze continues at this level.
+
+> e
+
+You are in a maze of twisty little passages, all alike.
+
+> nw
+
+Dead end
+
+There is an enormous ruby here!
+
+There are many coins here!
+
+There is precious jewelry here!
+
+There are diamonds here!
+
+The pirate's treasure chest is here!
+
+> drop rod
+
+OK
+
+> take jewelry
+
+OK
+
+> take chest
+
+OK
+
+> take ruby
+
+OK
+
+> take diamonds
+
+OK
+
+> take coins
+
+OK
+
+> se
+
+There is a threatening little dwarf in the room with you!
+
+You are in a maze of twisty little passages, all alike.
+
+> w
+
+There is a threatening little dwarf in the room with you!
+
+You are in a maze of twisty little passages, all alike.
+
+> s
+
+There is a threatening little dwarf in the room with you!
+
+You're at brink of pit.
+
+> d
+
+You're in bird chamber.
+
+> debris
+
+You're in debris room.
+
+> xyzzy
+
+>>Foof!<<
+
+You're inside building.
+
+There is a Persian rug spread out on the floor!
+
+There are bars of silver here!
+
+There is a large sparkling nugget of gold here!
+
+A precious jade necklace has been dropped here!
+
+There is a small wicker cage discarded nearby.
+
+There is a little bird in the cage.
+
+There is an emerald here the size of a plover's egg!
+
+There is a bottle of oil here.
+
+There is a delicate, precious, ming vase here!
+
+A small velvet pillow lies on the floor.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+There are some keys on the ground here.
+
+There is food here.
+
+> off
+
+Your lamp is now off.
+
+> drop coins
+
+OK
+
+> drop diamonds
+
+OK
+
+> drop jewelry
+
+OK
+
+> drop chest
+
+OK
+
+> drop lamp
+
+OK
+
+> take rug
+
+OK
+
+> take emerald
+
+OK
+
+> take cage
+
+OK
+
+> take bottle
+
+OK
+
+> w
+
+You're in front of building.
+
+> s
+
+You are in a valley in the forest beside a stream tumbling along a
+rocky bed.
+
+> w
+
+You are wandering aimlessly through the forest.
+
+> drop bird
+
+OK
+
+> listen
+
+The bird is singing to you in gratitude for your having returned it to
+its home.  In return, it informs you of a magic word which it thinks
+you may find useful somewhere near the Hall of Mists.  The magic word
+changes frequently, but for now the bird believes it is "N'BEH".  You
+thank the bird for this information, and it flies off into the forest.
+
+> drop cage
+
+OK
+
+> n
+
+You are wandering aimlessly through the forest.
+
+Your keen eye spots a severed leporine appendage lying on the ground.
+
+> take appendage
+
+OK
+
+> n
+
+You are wandering aimlessly through the forest.
+
+> e
+
+You are wandering aimlessly through the forest.
+
+> n
+
+You are wandering aimlessly through the forest.
+
+> n
+
+The forest thins out here to reveal a steep cliff.  There is no way
+down, but a small ledge can be seen to the west across the chasm.
+
+A small urn is embedded in the rock.
+
+> fill urn
+
+Your bottle is now empty and the urn is full of oil.
+
+> light urn
+
+The urn is now lit.
+
+> rub urn
+
+As you rub the urn, there is a flash of light and a genie appears.
+His aspect is stern as he advises: "One who wouldst traffic in
+precious stones must first learn to recognize the signals thereof."
+He wrests the urn from the stone, leaving a small cavity.  Turning to
+face you again, he fixes you with a steely eye and intones: "Caution!"
+Genie and urn vanish in a cloud of amber smoke.  The smoke condenses
+to form a rare amber gemstone, resting in the cavity in the rock.
+
+> drop rug
+
+OK
+
+> take amber
+
+OK
+
+> drop emerald
+
+The gem fits easily into the cavity.
+
+The Persian rug stiffens and rises a foot or so off the ground.
+
+> fly
+
+You board the Persian rug, which promptly whisks you across the chasm.
+You have time for a fleeting glimpse of a two thousand foot drop to a
+mighty river; then you find yourself on the other side.
+
+You are on a small ledge on one face of a sheer cliff.  There are no
+paths away from the ledge.  Across the chasm is a small clearing
+surrounded by forest.
+
+There is a Persian rug here, hovering in mid-air!
+
+A brilliant blue star sapphire is here!
+
+> take sapphire
+
+OK
+
+> fly
+
+The rug ferries you back across the chasm.
+
+You're at cliff.
+
+There is an emerald resting in a small cavity in the rock!
+
+There is a Persian rug here, hovering in mid-air!
+
+> take emerald
+
+OK
+
+> drop ruby
+
+The gem fits easily into the cavity.
+
+The Persian rug settles gently to the ground.
+
+> take rug
+
+OK
+
+> take ruby
+
+OK
+
+> e
+
+You are wandering aimlessly through the forest.
+
+> s
+
+You are wandering aimlessly through the forest.
+
+> e
+
+You have walked up a hill, still in the forest.  The road slopes back
+down the other side of the hill.  There is a building in the distance.
+
+> e
+
+You're in front of building.
+
+> e
+
+You are inside a building, a well house for a large spring.
+
+There is a shiny brass lamp nearby.
+
+The pirate's treasure chest is here!
+
+There is precious jewelry here!
+
+There are diamonds here!
+
+There are many coins here!
+
+There are bars of silver here!
+
+There is a large sparkling nugget of gold here!
+
+A precious jade necklace has been dropped here!
+
+There is a delicate, precious, ming vase here!
+
+A small velvet pillow lies on the floor.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+There are some keys on the ground here.
+
+There is food here.
+
+> drop emerald
+
+OK
+
+> drop ruby
+
+OK
+
+> drop amber
+
+OK
+
+> drop rug
+
+OK
+
+> drop sapphire
+
+OK
+
+> fill bottle
+
+Your bottle is now full of water.
+
+> take lamp
+
+OK
+
+> plugh
+
+>>Foof!<<
+
+It is now pitch dark.  If you proceed you will likely fall into a pit.
+
+> on
+
+Your lamp is now on.
+
+You're at "Y2".
+
+There is a little axe here.
+
+> s
+
+You're in n/s passage above e/w passage.
+
+> s
+
+You're in Hall of Mt King.
+
+> sw
+
+You're in secret e/w canyon above tight canyon.
+
+> w
+
+You are in a secret canyon which exits to the north and east.
+
+The body of a huge green dead dragon is lying off to one side.
+
+> n
+
+You are in a secret n/s canyon above a large room.
+
+> reservoir
+
+You are at the edge of a large underground reservoir.  An opaque cloud
+of white mist fills the room and rises rapidly upward.  The lake is
+fed by a stream, which tumbles out of a hole in the wall about 10 feet
+overhead and splashes noisily into the water somewhere within the
+mist.  There is a passage going back toward the south.
+
+> n'beh
+
+The waters have parted to form a narrow path across the reservoir.
+
+> n
+
+You are walking across the bottom of the reservoir.  Walls of water
+rear up on either side.  The roar of the water cascading past is
+nearly deafening, and the mist is so thick you can barely see.
+
+> n
+
+You are at the northern edge of the reservoir.  A northwest passage
+leads sharply up from here.
+
+The waters have parted to form a narrow path across the reservoir.
+
+> u
+
+You are scrambling along a treacherously steep, rocky passage.
+
+> u
+
+You are on a very steep incline, which widens at it goes upward.
+
+> u
+
+You are at the base of a nearly vertical cliff.  There are some
+slim footholds which would enable you to climb up, but it looks
+extremely dangerous.  Here at the base of the cliff lie the remains
+of several earlier adventurers who apparently failed to make it.
+
+> u
+
+You are climbing along a nearly vertical cliff.
+
+> u
+
+Just as you reach the top, your foot slips on a loose rock and you
+make one last desperate grab.  Your luck holds, as does your grip.
+With an enormous heave, you lift yourself to the ledge above.
+
+You are on a small ledge at the top of a nearly vertical cliff.
+There is a low crawl leading off to the northeast.
+
+> ne
+
+You have reached a dead end.
+
+There is a richly-carved ebony statuette here!
+
+> take statuette
+
+OK
+
+> sw
+
+You're at top of cliff.
+
+> d
+
+You are climbing along a nearly vertical cliff.
+
+> d
+
+You're at base of cliff.
+
+> d
+
+You are on a very steep incline, which widens at it goes upward.
+
+> d
+
+You are scrambling along a treacherously steep, rocky passage.
+
+> d
+
+You're north of reservoir.
+
+The waters have parted to form a narrow path across the reservoir.
+
+> s
+
+You're at bottom of reservoir.
+
+> s
+
+You're at reservoir.
+
+The waters have parted to form a narrow path across the reservoir.
+
+> s
+
+You are in a north/south canyon about 25 feet across.  The floor is
+covered by white mist seeping in from the north.  The walls extend
+upward for well over 100 feet.  Suspended from some unseen point far
+above you, an enormous two-sided mirror is hanging parallel to and
+midway between the canyon walls.  (The mirror is obviously provided
+for the use of the dwarves who, as you know, are extremely vain.)  A
+small window can be seen in either wall, some fifty feet up.
+
+> s
+
+You are in a secret n/s canyon above a large room.
+
+> d
+
+You are in a large low circular chamber whose floor is an immense slab
+fallen from the ceiling (Slab Room).  East and west there once were
+large passages, but they are now filled with boulders.  Low small
+passages go north and south, and the south one quickly bends west
+around the boulders.
+
+> s
+
+You're at west end of Twopit Room.
+
+The top of a 12-foot-tall beanstalk is poking out of the west pit.
+
+> d
+
+You're in west pit.
+
+There is a 12-foot-tall beanstalk stretching up out of the pit,
+bellowing "WATER!! WATER!!"
+
+> water plant
+
+The plant grows explosively, almost filling the bottom of the pit.
+
+You're in west pit.
+
+There is a gigantic beanstalk stretching all the way up to the hole.
+
+> u
+
+You're at west end of Twopit Room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> e
+
+You're at east end of Twopit Room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> d
+
+You're in east pit.
+
+> fill bottle
+
+Your bottle is now full of oil.
+
+> u
+
+You're at east end of Twopit Room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> w
+
+You're at west end of Twopit Room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> d
+
+You're in west pit.
+
+There is a gigantic beanstalk stretching all the way up to the hole.
+
+> climb
+
+You clamber up the plant and scurry through the hole at the top.
+
+You are in a long, narrow corridor stretching out of sight to the
+west.  At the eastern end is a hole through which you can see a
+profusion of leaves.
+
+> w
+
+You are in the Giant Room.  The ceiling here is too high up for your
+lamp to show it.  Cavernous passages lead east, north, and south.  On
+the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic].
+
+There is a large nest here, full of golden eggs!
+
+> take eggs
+
+OK
+
+> n
+
+You are at one end of an immense north/south passage.
+
+The way north is barred by a massive, rusty, iron door.
+
+> oil door
+
+The oil has freed up the hinges so that the door will now move,
+although it requires some effort.
+
+> drop bottle
+
+OK
+
+> n
+
+You are in a magnificent cavern with a rushing stream, which cascades
+over a sparkling waterfall into a roaring whirlpool which disappears
+through a hole in the floor.  Passages exit to the south and west.
+
+There is a jewel-encrusted trident here!
+
+> take trident
+
+OK
+
+> w
+
+You are at the top of a steep incline above a large room.  You could
+climb down here, but you would not be able to climb up.  There is a
+passage leading back to the north.
+
+> d
+
+You are in a large low room.  Crawls lead north, se, and sw.
+
+> bedquilt
+
+You're in Bedquilt.
+
+> e
+
+You're at complex junction.
+
+> n
+
+You're in a large room carved out of sedimentary rock.  The floor and
+walls are littered with bits of shells embedded in the stone.  A
+shallow passage proceeds downward, and a somewhat steeper one leads
+up.  A low hands and knees passage enters from the south.
+
+There is an enormous clam here with its shell tightly closed.
+
+> open clam
+
+A glistening pearl falls out of the clam and rolls away.  Goodness,
+this must really be an oyster.  (I never was very good at identifying
+bivalves.)  Whatever it is, it has now snapped shut again.
+
+> d
+
+You are in a long sloping corridor with ragged sharp walls.
+
+> d
+
+You are in a cul-de-sac about eight feet across.
+
+Off to one side lies a glistening pearl!
+
+> take pearl
+
+OK
+
+> shell
+
+You're in Shell Room.
+
+There is an enormous oyster here with its shell tightly closed.
+
+> s
+
+You're at complex junction.
+
+> u
+
+You're in dusty rock room.
+
+> e
+
+You're in dirty passage.
+
+> u
+
+You're in n/s passage above e/w passage.
+
+> n
+
+You're at "Y2".
+
+There is a little axe here.
+
+> plugh
+
+>>Foof!<<
+
+You're inside building.
+
+A brilliant blue star sapphire is here!
+
+There is a Persian rug spread out on the floor!
+
+There is a rare amber gemstone here!
+
+There is an enormous ruby here!
+
+There is an emerald here the size of a plover's egg!
+
+The pirate's treasure chest is here!
+
+There is precious jewelry here!
+
+There are diamonds here!
+
+There are many coins here!
+
+There are bars of silver here!
+
+There is a large sparkling nugget of gold here!
+
+A precious jade necklace has been dropped here!
+
+There is a delicate, precious, ming vase here!
+
+A small velvet pillow lies on the floor.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+There are some keys on the ground here.
+
+There is food here.
+
+> drop trident
+
+OK
+
+> drop pearl
+
+OK
+
+> drop statuette
+
+OK
+
+> drop appendage
+
+OK
+
+> take keys
+
+OK
+
+> take food
+
+OK
+
+> plugh
+
+>>Foof!<<
+
+You are in a large room, with a passage to the south, a passage to the
+west, and a wall of broken rock to the east.  There is a large "Y2" on
+a rock in the room's center.
+
+There is a little axe here.
+
+> s
+
+You are in a low n/s passage at a hole in the floor.  The hole goes
+down to an e/w passage.
+
+> d
+
+You're in dirty passage.
+
+> bedquilt
+
+You're in Bedquilt.
+
+> w
+
+You're in Swiss Cheese Room.
+
+> oriental
+
+You're in Oriental Room.
+
+> w
+
+You're in large low room.
+
+> sw
+
+You are in a long winding corridor sloping out of sight in both
+directions.
+
+> u
+
+You are on one side of a large, deep chasm.  A heavy white mist rising
+up from below obscures all view of the far side.  A sw path leads away
+from the chasm into a winding corridor.
+
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
+
+A burly troll stands by the bridge and insists you throw him a
+treasure before you may cross.
+
+> throw eggs
+
+The troll catches your treasure and scurries away out of sight.
+
+> ne
+
+You are on the far side of the chasm.  A ne path leads away from the
+chasm on this side.
+
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
+
+The troll is nowhere to be seen.
+
+> barren
+
+You are standing at the entrance to a large, barren room.  A notice
+above the entrance reads:  "Caution!  Bear in room!"
+
+> e
+
+You are inside a barren room.  The center of the room is completely
+empty except for some dust.  Marks in the dust lead away toward the
+far end of the room.  The only exit is the way you came in.
+
+There is a ferocious cave bear eyeing you from the far end of the room!
+
+The bear is locked to the wall with a golden chain!
+
+> throw food
+
+The bear eagerly wolfs down your food, after which he seems to calm
+down considerably and even becomes rather friendly.
+
+> unlock chain
+
+The chain is now unlocked.
+
+> take chain
+
+OK
+
+> take bear
+
+OK
+
+> fork
+
+You are being followed by a very large, tame bear.
+
+The path forks here.  The left fork leads northeast.  A dull rumbling
+seems to get louder in that direction.  The right fork leads southeast
+down a gentle slope.  The main corridor enters from the west.
+
+> ne
+
+You are being followed by a very large, tame bear.
+
+The walls are quite warm here.  From the north can be heard a steady
+roar, so loud that the entire cave seems to be trembling.  Another
+passage leads south, and a low crawl goes east.
+
+> fee
+
+OK
+
+> fie
+
+OK
+
+> foe
+
+OK
+
+> foo
+
+Done!
+
+> e
+
+You are being followed by a very large, tame bear.
+
+You are in a small chamber filled with large boulders.  The walls are
+very warm, causing the air in the room to be almost stifling from the
+heat.  The only exit is a crawl heading west, through which is coming
+a low rumbling.
+
+There are rare spices here!
+
+> take spices
+
+OK
+
+> fork
+
+You are being followed by a very large, tame bear.
+
+You're at fork in path.
+
+> w
+
+You are being followed by a very large, tame bear.
+
+You're in a long east/west corridor.  A faint rumbling noise can be
+heard in the distance.
+
+> w
+
+You are being followed by a very large, tame bear.
+
+You're on ne side of chasm.
+
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
+
+The troll is nowhere to be seen.
+
+> sw
+
+The troll steps out from beneath the bridge and blocks your way.
+
+You are being followed by a very large, tame bear.
+
+You're on ne side of chasm.
+
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
+
+A burly troll stands by the bridge and insists you throw him a
+treasure before you may cross.
+
+> release bear
+
+The bear lumbers toward the troll, who lets out a startled shriek and
+scurries away.  The bear soon gives up the pursuit and wanders back.
+
+> sw
+
+You're on sw side of chasm.
+
+A rickety wooden bridge extends across the chasm, vanishing into the
+mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
+
+The troll is nowhere to be seen.
+
+> sw
+
+You're in sloping corridor.
+
+> d
+
+You're in large low room.
+
+> se
+
+You're in Oriental Room.
+
+> se
+
+You are in a room whose walls resemble Swiss cheese.  Obvious passages
+go west, east, ne, and nw.  Part of the room is occupied by a large
+bedrock block.
+
+> w
+
+You are at the east end of the Twopit Room.  The floor here is
+littered with thin rock slabs, which make it easy to descend the pits.
+There is a path here bypassing the pits to connect passages from east
+and west.  There are holes all over, but the only big one is on the
+wall directly over the west pit where you can't get to it.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> w
+
+You are at the west end of the Twopit Room.  There is a large hole in
+the wall above the pit at this end of the room.
+
+There is a huge beanstalk growing out of the west pit up to the hole.
+
+> d
+
+You are at the bottom of the western pit in the Twopit Room.  There is
+a large hole in the wall about 25 feet above you.
+
+There is a gigantic beanstalk stretching all the way up to the hole.
+
+> climb
+
+You clamber up the plant and scurry through the hole at the top.
+
+You're in narrow corridor.
+
+> w
+
+You're in Giant Room.
+
+There is a large nest here, full of golden eggs!
+
+> take eggs
+
+OK
+
+> n
+
+You are at one end of an immense north/south passage.
+
+There is an empty bottle here.
+
+The way north leads through a massive, rusty, iron door.
+
+> n
+
+You're in cavern with waterfall.
+
+> w
+
+You're at steep incline above large room.
+
+> d
+
+You're in large low room.
+
+> bedquilt
+
+You're in Bedquilt.
+
+> e
+
+You're at complex junction.
+
+> u
+
+You're in dusty rock room.
+
+> e
+
+You're in dirty passage.
+
+> u
+
+You're in n/s passage above e/w passage.
+
+> n
+
+There is a threatening little dwarf in the room with you!
+
+One sharp nasty knife is thrown at you!
+
+It misses!
+
+You're at "Y2".
+
+There is a little axe here.
+
+> plugh
+
+>>Foof!<<
+
+You're inside building.
+
+Your keen eye spots a severed leporine appendage lying on the ground.
+
+There is a richly-carved ebony statuette here!
+
+Off to one side lies a glistening pearl!
+
+There is a jewel-encrusted trident here!
+
+A brilliant blue star sapphire is here!
+
+There is a Persian rug spread out on the floor!
+
+There is a rare amber gemstone here!
+
+There is an enormous ruby here!
+
+There is an emerald here the size of a plover's egg!
+
+The pirate's treasure chest is here!
+
+There is precious jewelry here!
+
+There are diamonds here!
+
+There are many coins here!
+
+There are bars of silver here!
+
+There is a large sparkling nugget of gold here!
+
+A precious jade necklace has been dropped here!
+
+There is a delicate, precious, ming vase here!
+
+A small velvet pillow lies on the floor.
+
+There is a platinum pyramid here, 8 inches on a side!
+
+> drop eggs
+
+OK
+
+> drop chain
+
+OK
+
+> drop spices
+
+OK
+
+> plugh
+
+>>Foof!<<
+
+You're at "Y2".
+
+A hollow voice says "PLUGH".
+
+There is a little axe here.
+
+> s
+
+You're in n/s passage above e/w passage.
+
+> look
+
+Sorry, but I am not allowed to give more detail.  I will repeat the
+long description of your location.
+
+You are in a low n/s passage at a hole in the floor.  The hole goes
+down to an e/w passage.
+
+> look
+
+Sorry, but I am not allowed to give more detail.  I will repeat the
+long description of your location.
+
+You are in a low n/s passage at a hole in the floor.  The hole goes
+down to an e/w passage.
+
+> n
+
+A sepulchral voice reverberating through the cave, says, "Cave closing
+soon.  All adventurers exit immediately through main office."
+
+You're at "Y2".
+
+There is a little axe here.
+
+> plugh
+
+A mysterious recorded voice groans into life and announces:
+   "This exit is closed.  Please leave via main office."
+
+You're at "Y2".
+
+There is a little axe here.
+
+> s
+
+You're in n/s passage above e/w passage.
+
+> d
+
+You are in a dirty broken passage.  To the east is a crawl.  To the
+west is a large passage.  Above you is a hole to another passage.
+
+> w
+
+You're in dusty rock room.
+
+> d
+
+You're at complex junction.
+
+> e
+
+You are in an anteroom leading to a large passage to the east.  Small
+passages go west and up.  The remnants of recent digging are evident.
+A sign in midair here says "Cave under construction beyond this point.
+Proceed at own risk.  [Witt Construction Company]"
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> take magazine
+
+OK
+
+> e
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+> drop magazine
+
+OK
+
+> look
+
+Sorry, but I am not allowed to give more detail.  I will repeat the
+long description of your location.
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> look
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> look
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> look
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> look
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> look
+
+You are at Witt's End.  Passages lead off in *ALL* directions.
+
+There are a few recent issues of "Spelunker Today" magazine here.
+
+> look
+
+The sepulchral voice intones, "The cave is now closed."  As the echoes
+fade, there is a blinding flash of light (and a small puff of orange
+smoke). . . .    As your eyes refocus, you look around and find...
+
+You are at the northeast end of an immense room, even larger than the
+Giant Room.  It appears to be a repository for the "Adventure"
+program.  Massive torches far overhead bathe the room with smoky
+yellow light.  Scattered about you can be seen a pile of bottles (all
+of them empty), a nursery of young beanstalks murmuring quietly, a bed
+of oysters, a bundle of black rods with rusty stars on their ends, and
+a collection of brass lanterns.  Off to one side a great many dwarves
+are sleeping on the floor, snoring loudly.  A notice nearby reads: "Do
+not disturb the dwarves!"  An immense mirror is hanging against one
+wall, and stretches to the other end of the room, where various other
+sundry objects can be glimpsed dimly in the distance.
+
+> sw
+
+You are at the southwest end of the repository.  To one side is a pit
+full of fierce green snakes.  On the other side is a row of small
+wicker cages, each of which contains a little sulking bird.  In one
+corner is a bundle of black rods with rusty marks on their ends.  A
+large number of velvet pillows are scattered about on the floor.  A
+vast mirror stretches off to the northeast.  At your feet is a large
+steel grate, next to which is a sign that reads, "Treasure Vault.
+Keys in main office."
+
+The grate is locked.
+
+> take rod
+
+OK
+
+> ne
+
+You're at ne end.
+
+> drop rod
+
+OK
+
+> sw
+
+You're at sw end.
+
+The grate is locked.
+
+> blast
+
+There is a loud explosion, and a twenty-foot hole appears in the far
+wall, burying the dwarves in the rubble.  You march through the hole
+and find yourself in the main office, where a cheering band of
+friendly elves carry the conquering adventurer off into the sunset.
+
+You scored 430 out of a possible 430, using 349 turns.
+
+Adventuredom stands in awe -- you have now joined the ranks of the
+       W O R L D   C H A M P I O N   A D V E N T U R E R S !
+It may interest you to know that the Dungeon-Master himself has, to
+my knowledge, never achieved this threshold in fewer than 330 turns.
+
+To achieve the next higher rating would be a neat trick!
+Congratulations!!
diff --git a/tests/win430.log b/tests/win430.log
new file mode 100644
index 0000000..beaa8d4
--- /dev/null
+++ b/tests/win430.log
@@ -0,0 +1,355 @@
+## Ryan Sarson's 430-point win.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+no
+seed 1318612053
+e
+plugh
+plove
+get emerald
+w
+drop emerald
+e
+ne
+get pyramid
+s
+plove
+plugh
+drop pyramid
+get lamp
+get water
+plugh
+on
+s
+d
+bedquilt
+w
+e
+take pillow
+w
+oriental
+take vase
+n
+w
+take emerald
+nw
+s
+se
+w
+w
+d
+water plant
+u
+e
+d
+fill bottle
+u
+e
+ne
+e
+u
+e
+u
+n
+plugh
+drop pillow
+drop vase
+drop bottle
+drop emerald
+xyzzy
+take rod
+e
+take cage
+pit
+drop rod
+e
+take bird
+w
+drop bird
+take rod
+wave rod
+take necklace
+drop rod
+take bird
+d
+s
+take nugget
+n
+n
+drop bird
+take bird
+sw
+w
+kill dragon
+yes
+drink blood
+take rug
+e
+e
+n
+take bars
+n
+plugh
+drop cage
+drop necklace
+drop nugget
+drop bars
+drop rug
+xyzzy
+pit
+take rod
+d
+w
+wave rod
+w
+take diamonds
+w
+w
+w
+s
+s
+e
+s
+hit machine
+s
+s
+kill ogre
+n
+take ruby
+s
+w
+n
+n
+sw
+w
+d
+n
+e
+take coins
+e
+s
+take jewelry
+n
+e
+w
+w
+w
+s
+e
+s
+s
+s
+n
+e
+e
+nw
+drop rod
+take jewelry
+take chest
+take ruby
+take diamonds
+take coins
+se
+w
+s
+d
+debris
+xyzzy
+off
+drop coins
+drop diamonds
+drop jewelry
+drop chest
+drop lamp
+take rug
+take emerald
+take cage
+take bottle
+w
+s
+w
+drop bird
+listen
+drop cage
+n
+take appendage
+n
+e
+n
+n
+fill urn
+light urn
+rub urn
+drop rug
+take amber
+drop emerald
+fly
+take sapphire
+fly
+take emerald
+drop ruby
+take rug
+take ruby
+e
+s
+e
+e
+e
+drop emerald
+drop ruby
+drop amber
+drop rug
+drop sapphire
+fill bottle
+take lamp
+plugh
+on
+s
+s
+sw
+w
+n
+reservoir
+n'beh
+n
+n
+u
+u
+u
+u
+u
+ne
+take statuette
+sw
+d
+d
+d
+d
+d
+s
+s
+s
+s
+d
+s
+d
+water plant
+u
+e
+d
+fill bottle
+u
+w
+d
+climb
+w
+take eggs
+n
+oil door
+drop bottle
+n
+take trident
+w
+d
+bedquilt
+e
+n
+open clam
+d
+d
+take pearl
+shell
+s
+u
+e
+u
+n
+plugh
+drop trident
+drop pearl
+drop statuette
+drop appendage
+take keys
+take food
+plugh
+s
+d
+bedquilt
+w
+oriental
+w
+sw
+u
+throw eggs
+ne
+barren
+e
+throw food
+unlock chain
+take chain
+take bear
+fork
+ne
+fee
+fie
+foe
+foo
+e
+take spices
+fork
+w
+w
+sw
+release bear
+sw
+sw
+d
+se
+se
+w
+w
+d
+climb
+w
+take eggs
+n
+n
+w
+d
+bedquilt
+e
+u
+e
+u
+n
+plugh
+drop eggs
+drop chain
+drop spices
+plugh
+s
+look
+look
+n
+plugh
+s
+d
+w
+d
+e
+take magazine
+e
+drop magazine
+look
+look
+look
+look
+look
+look
+look
+sw
+take rod
+ne
+drop rod
+sw
+blast
diff --git a/tests/wittsend.chk b/tests/wittsend.chk
index dcd9bd4..b92cf2f 100644
--- a/tests/wittsend.chk
+++ b/tests/wittsend.chk
@@ -2628,7 +2628,7 @@ It is now pitch dark.  If you proceed you will likely fall into a pit.
 
 You're in Plover Room.
 
-
+> 
 You scored 342 out of a possible 430, using 423 turns.
 
 Your score puts you in Master Adventurer Class C.
diff --git a/tests/wittsend.log b/tests/wittsend.log
index 580f7c8..5ae3ec0 100644
--- a/tests/wittsend.log
+++ b/tests/wittsend.log
@@ -1,4 +1,6 @@
 ## 342-point run to Witt's End and plover room.
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
 # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56
 n
 seed 1635997320
diff --git a/tests/woodshint.chk b/tests/woodshint.chk
index c26d471..7ea7cdd 100644
--- a/tests/woodshint.chk
+++ b/tests/woodshint.chk
@@ -314,7 +314,7 @@ You are wandering aimlessly through the forest.
 
 You're at end of road.
 
-
+> 
 You scored 30 out of a possible 430, using 45 turns.
 
 You are obviously a rank amateur.  Better luck next time.
diff --git a/tests/woodshint.log b/tests/woodshint.log
index 6db609a..68b2e38 100644
--- a/tests/woodshint.log
+++ b/tests/woodshint.log
@@ -1,4 +1,7 @@
 ## Test hinting logic - elicit forest hint
+# SPDX-FileCopyrightText: Eric S. Raymond <esr@thyrsus.com>
+# SPDX-License-Identifier: BSD-2-Clause
+#NOCOMPARE Behavior differs due to a parser bug fix.
 # Also some tests of intransitive-verb cases
 n
 seed 2099333241
@@ -63,4 +66,4 @@ n
 n
 n
 w
-n
\ No newline at end of file
+n

More details

Full run details

Historical runs