GDT and Testing
In order to test the port of Dungeon (mainframe Zork) to Sharpee, I obviously needed a testing infrastructure. I had already implemented a transcript system that allows the author to create .transcript files and run the test harness. This is the transcript file for the mailbox:
title: Mailbox and Leaflet
story: dungeo
description: Test opening mailbox and reading the leaflet
---
# Examine the mailbox
> examine mailbox
[OK: contains "small mailbox"]
[EVENT: true, type="if.event.examined"]
# Open the mailbox
> open mailbox
[OK: contains "open"]
[EVENT: true, type="if.event.opened"]
[EVENT: true, type="action.success"]
[EVENT: false, type="action.blocked"]
# Search inside the mailbox
> search mailbox
[OK: contains "leaflet"]
[EVENT: true, type="if.event.searched"]
# Take the leaflet
> take leaflet
[OK: contains "take"]
[OK: contains "leaflet"]
[EVENT: true, type="if.event.taken"]
# Read it
> read leaflet
[OK: contains "DUNGEO"]
[EVENT: true, type="action.success"]
# Check inventory
> inventory
[OK: contains "carrying"]
[OK: contains "leaflet"]
# Put it back
> put leaflet in mailbox
[OK: contains "put"]
[EVENT: true, type="if.event.put_in"]
[EVENT: true, type="action.success"]
# Close the mailbox
> close mailbox
[OK: contains "close"]
[EVENT: true, type="if.event.closed"]
[EVENT: true, type="action.success"]Sharpee is an event-based system, so being able to test text emissions and the existence of events or a lack of their existence is used to validate story development.
Of course we still have the issue of testing deep into the game and it would be tedious to setup the world model in a particular state before testing or running one super long transcript. The later versions of mainframe Zork had a debugging tool the player could use called GDT. It had the ability to be blocked with a code, but the last VAX implementation had gdtFLAG:1, so it was always available.
I dug up the entire command list and adapted it to the port. We had to make one change to the game engine, allowing a hook before CommandValidator, but that's an easy change to tolerate. It doesn't break continuity or architecture. We also have AuthorModel to allow GDT to make mutations in the world model without validation. This means the player can get things from anywhere at any time using the correct GDT command.
Original GDT Commands (38 total)
Display Commands (15)
| Cmd | Name | Original Purpose | Sharpee Equivalent |
|---|---|---|---|
DR | Display Rooms | Show room properties | List room entities with traits |
DO | Display Objects | Show object properties | List object entities with traits |
DA | Display ADVS | Show adventurer state | Show player inventory, location, score |
DC | Display CEVENT | Show clock events | List active daemons/fuses (ADR-071) |
DX | Display Exits | Show room exits | List room connections |
DH | Display Hacks | Show debug vars | Show thief activity, sword glow, etc. |
DL | Display Lengths | Show array sizes | Show entity counts by type |
DV | Display Villains | Show villain state | Show NPC state (ADR-070) |
DF | Display Flags | Show game flags | Show world state flags |
DS | Display State | Show overall state | Show turn count, score, game phase |
DN | Display Switches | Show switch values | Show boolean world state |
DM | Display Messages | Show message indices | List message IDs |
DT | Display Text | Print text by index | Print message by ID |
DP | Display Parser | Show parser state | Show last parse result |
D2 | Display ROOM2 | Secondary room data | Show room metadata |
DZ | Display Puzzle | Puzzle room grid | Show Royal Puzzle state |
Alter Commands (9)
| Cmd | Name | Original Purpose | Sharpee Equivalent |
|---|---|---|---|
AH | Alter HERE | Teleport player | Move player to room by ID |
AO | Alter Objects | Move objects | Set entity location |
AR | Alter Rooms | Modify room props | Set room traits |
AF | Alter Flags | Modify game flags | Set world state |
AC | Alter CEVENT | Modify timers | Adjust daemon/fuse timing |
AA | Alter ADVS | Modify player | Set score, inventory, etc. |
AX | Alter Exits | Modify connections | Add/remove room exits |
AV | Alter Villains | Modify NPC state | Set NPC properties |
AN | Alter Switches | Modify switches | Set world booleans |
AZ | Alter Puzzle | Modify puzzle | Set Royal Puzzle state |
Villain Toggle Commands (8)
| Cmd | Name | Original Purpose |
|---|---|---|
NC | No Cyclops | Disable cyclops |
ND | No Deaths | Enable immortality |
NR | No Robber | Disable thief |
NT | No Troll | Disable troll |
RC | Restore Cyclops | Re-enable cyclops |
RD | Restore Deaths | Disable immortality |
RR | Restore Robber | Re-enable thief |
RT | Restore Troll | Re-enable troll |
Utility Commands (4)
| Cmd | Name | Original Purpose |
|---|---|---|
TK | Take | Acquire any object |
PD | Program Detail | Toggle verbose debug |
HE | Help | List GDT commands |
EX | Exit | Return to game |
We did not implement AF and DF since those are unique to the MDL/Fortran implementations.
Here's a transcript test for GDT that shows its capabilities:
title: GDT Unrestricted Access
story: dungeo
description: Tests that GDT can access and manipulate entities regardless of visibility
---
# Uses the parsed command transformer to bypass entity validation
# Enter GDT mode
> gdt
[OK: contains "GAME DEBUGGING TOOL"]
# Test TK with multi-word entity name (not visible from starting location)
# The brass lantern is in the living room, not visible from West of House
> tk brass lantern
[OK: contains "Taken: brass lantern"]
# Verify we got it in inventory
> da
[OK: contains "brass lantern (i06)"]
# Test AO to move something to a location we're not in
# Move the lantern to the kitchen (single-word location)
> ao brass lantern kitchen
[OK: contains "Moved: brass lantern -> Kitchen"]
# Test DR to verify it moved
> dr kitchen
[OK: contains "brass lantern (i06)"]
# Take it back
> tk brass lantern
[OK: contains "Taken: brass lantern"]
# Test AO with special location 'player'
> ao brass lantern player
[OK: contains "Moved: brass lantern -> player inventory"]
# Verify in inventory
> da
[OK: contains "brass lantern (i06)"]
# Exit GDT
> ex
[OK: contains "Returning to game"]
# Verify we still have the lantern after exiting GDT
> inventory
[OK: contains "brass lantern"]