Nightcrawler: A Miniature Embeddable Text Adventure Engine

Nightcrawler is a multiplatform text adventure engine designed to be as small as possible (enough to fit on a floppy disk). It accomplishes these goals by using the C programming language, and is meant to be compatible with common toolchains like GCC, Clang, and MinGW-w64. The engine was commissioned by Dan Butler from Techno Mage. It is open source and licensed under the BSD 3-clause license.

Nightcrawler is available on both GitHub and GitLab. Binary distributions for Linux x86_64, Win32, and Win64 are available from the GitHub mirror.

Nightcrawler is still in development and plans for its future are discussed at the proposed features page.

As of writing, Nightcrawler is proven to be capable of running on:

Other platforms will likely work, though big endian platforms may not since addresses in story files are little endian encoded, and the engine is, at-present, unable to detect the endianness of its platform.

As a small note, Nightcrawler does not support building under Alpine Linux or other Musl-based systems. There are no plans to add support for these platforms as the primary target of Nightcrawler is Windows via MinGW-w64.

Usage

Nightcrawler's binary can be invoked as a standard application in your environment, and respects several command-line parameters.

Command Line Options
-f [FILE] or --file Select a different file. If this option is not passed, the engine defaults to default.nst in the folder you invoked the engine from.
--info Provides build info.
-h or --help Show a help message that describes invocation options.
--license Show the text of the BSD 3-clause license.

Nightcrawler is a command (user input) driven game engine. During gameplay the engine uses a set of predefined keywords. These are implemented using a gperf generated hash function. Keywords are case insensitive. A comprehensive list of available keywords is available on the project readme, and through the HELP command.

Keywords
HELP Displays a list of available keywords, and help included in the loaded story file. Usually some background about the story, as well as objectives and potentially copyright information.
MOVE or GO Moves to another scene if one is available. A direction parameter is required. Direction can be one of NORTH, SOUTH, EAST, or WEST. Optionally you may use initialisms like N, S, E or W.
LOOK or EXAMINE Trigger the look nodes for a scene. An optional direction parameter may be provided. The directions are the same as the MOVE command, but with the addition of an AROUND command. If no direction is given AROUND is assumed.
GET or GRAB or TAKE Adds the items(s) in the scene into the players inventory, and optionally displays a message.
TALK Triggers the beginning of a dialogue mode, or display a message stating there is no other person to converse with. Dialogue mode will present the user with numeric options provided by the story file, which may affect the game's internal state flags.
USE Interact with the scene's use node, or display a message stating you can't if this is not applicable. This should update the engine's state flags and show a message about what was used and how.
ITEMS or INVENTORY or INV Displays the names of items currently in the player's inventory. This is determined with the engine item flags. Item flags that do not possess names may elicit undefined bahavior.
SAVE and LOAD These save or load the game state to a file named nightcrawler.sav in the folder the engine was invoked from. These save file do not store the story file associated with them, so care must be taken to use the same story file with the same save files. Usually you'd do this by keeping save and story in the same folder.
QUIT or EXIT Cleanly stops the engine and exits.

Winning or losing the game may be done either via a move or use command. Winning will display a message describing the manner of victory, and prompt for a keypress before closing the game. Losing the game works in much the same way, showing a message stating the manner of loss, but instead restarting the game from the beginning.

Formatting & Operation

Writing Your Own Nightcrawler Stories

The Nightcrawler Story Format (NST) is responsible for handling all story data, and should be shipped separately from the engine. Stories are a custom node-based binary format. The layout of these files is described here for ease of use, but formal specs are defined in nstspecs.md. As stated earlier big endian platforms are not well supported by the engine.

The binary NST story format contains all data used by the Nightcrawler engine. the format is built around nodes, which are identified by magic number strings. Each magic number is four bytes long and consists of a three character, null-terminated C string (as Nightcrawler is implemented in C). Nodes are interconnected with addresses. All addressing is absolute, and all binary data is little-endian, and all strings are valid C strings, being null terminated, and using 8-bit chars. Many nodes have fields referred to as "required flags", these flags can be set in coordination with the engine's progress flags (item and story flags) to activate some type of alternate function of the node; be this alternative addresses or strings.

List of Node Types
Magic ID Description
NST "Story" node. These contain vital information about the story file overall, including the format version, addresses to global strings, item names, and the game's starting scene. Effectively acting as a header for the story file.
NSC "Scene" nodes. These are effective containers for linking together other types of nodes with each other.
MOV "Move" nodes, subnode of NSC nodes that point to either NSC, WIN, or DTH nodes, and allow the player to move around between scenes.
LOK "Look" nodes, subnode of NSC nodes that allow the player to use the LOOK command. These point to string for the various directions and allow branching similar to MOV nodes based on flags.
TLK "Talk" nodes, subnode of NSC nodes that define the beginning of a dialogue tree. They hold flags that are required to begin dialogue mode, and the address of the initial DIA node.
DIA DIA nodes hold information about a dialogue phase. Including flags required for alternate strings or flags to set and alternate flags to set. It also can include the address of a DOL node to use branching dialogue.
DOL Dialogue Option List nodes. This type of node differs from most of the others in that it has no fixed size. Instead it consists of a count and subsequent array of addresses to OPT nodes.
OPT Dialogue Option nodes define an option the player can choose in dialogue mode. They can set flags, and have required flags. All options in a DOL that pass the required flag checks will be displayed to the player. These can also branch to DIA nodes, and thus recurse down a branching dialogue system.
USE Defines the action of an USE command. This includes the string that is displayed, required flags, and the flags to set upon completion.
WIN and DTH These two nodes are structured identically, and act similarly. DTH (death) nodes will print their string and reset the game. WIN (win) nodes print their string and end the game. They can be called by MOV or USE nodes.

As for building one of these story files one of the best ways to do so is to use an external assembler like nasm or fasm. Whatever you're most comfortable with that lets you generate binary data with referential addresses inside it. At some point in the future there may be a compiler or editor for the story files, but at present no such thing exists.