Skip to content

Drakmyth/zork-godot

Repository files navigation

zork-godot

This is an implementation of the 1980 interactive fiction game Zork I built on the Godot game engine.

The ZIL (Zork Implementation Language) code published by historicalsource in 2019 served as a significant inspiration and source of reference. This project is not intended to be a direct port of that source, rather it serves as a proof of concept for building full-scale interactive fiction games using Godot.

The ZIL Manual published by Steven Eric Meretzky in 1995 and uploaded to the Internet Archive also served as a key source of reference.

How Does It Work

Game Loop

The Game scene functions as the primary entry point. It contains the entire game world, all UI elements, and the command parser. There is no main game loop. Instead all game logic is initiated by the Prompt scene firing a command_submitted event which it does in response to the text_submitted event from the standard LineEdit control.

From here the Game scene will pass the input text into the CommandParser.parse_input function along with a reference to the player. This function handles all tokenization and parsing logic and ultimately produces an array of Commands that represent a series of actions the player wishes to take. The Game will then execute each Command in turn and add the resulting response to the ResponseHistory interface. Finally, the Game will clear the previous input from the Prompt and await the player's next input.

Command Execution

All matters of language processing are handled by the auto-loaded Vocabulary script. Upon initialization, this script will dynamically load all Command resources in the res://commands directory and populate a lookup map using the metadata defined on those resources. This metadata defines the surrounding structure of the input text required for this command (What prepositions are allowed, how many object references does this command need, etc). When the CommandParser produces a collection of commands, it does so by analyzing the player's input text and finding commands whose metadata define a matching structure.

In order to execute a command, the Game will get that command's Request Chain. A Request Chain is an array of Callable handlers that each have the opportunity to handle the command execution. In order, these handlers are:

  1. Command.check_holding*
  2. Player.action
  3. Room.on_begin_command
  4. Command.preaction
  5. First** Indirect Object Thing.action
  6. First** Direct Object Thing.action
  7. Command.action

* This is handled here more for convenience. It is not intended to be modified or overridden.
** Additional objects after the first are ignored.

Each handler returns a response string. If that response is empty, execution passes to the next handler. If the response is not empty execution of the chain halts. After the chain has been processed, Room.on_end_command is called as a final handler before the response is returned and appended to the ResponseHistory.

💭 Basing execution on the response string return is a notable design flaw here. Because all the handlers need to execute before the final response can be built, it becomes complicated for commands to add text to the response without interrupting the Request Chain execution or to interrupt execution without providing a response string.

This is ultimately why system commands like restart and quit operate via dialog boxes instead of integrating with the parser. There was no way to pause normal command processing to handle the "Are you sure? y/n" sub-prompt.

When creating a new Command resource, make sure to update the Script reference in the inspector to point to the proper script in the res://command_scripts directory. Otherwise the default empty implementations of Command.preaction and Command.action will be called when the command is executed.

License

Distributed under the MIT License. See LICENSE.md for more information.

About

Zork I built with Godot

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published