Skip to content

About

A desktop GUI tool for browsing and inspecting the record-based game database files (`ADATA1`, `ADATA2`) used by the **Quest** text-adventure engine

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Quest Data File Viewer

A desktop GUI tool for browsing and inspecting the record-based game database files (ADATA1, ADATA2) used by the Quest text-adventure engine (Brendan Murray, 1992 / restarted 2023), as defined by questdefs.h.

It lets you page through every record in the database, see each record broken down into its named fields (place descriptions, moves/exits, artefacts, gremlins, puzzle conditions, vocabulary keys, and state initialisation), and jump straight to another record just by double-clicking a field that references it.

(add a screenshot here once you've run it, e.g. screenshots/place_record.png)


Contents


Background

Quest games store all their content — places, objects, creatures, text and puzzle logic — in a flat, fixed-length record file. questdefs.h defines the C structures the original engine uses to interpret those records. This repository documents the on-disk format (reverse-engineered from sample ADATA1 / ADATA2 files plus the header comments) and provides a standalone Python viewer so the data can be inspected without compiling or running the original game engine.

File format

Confirmed from the sample data files:

  • Every record is exactly 100 ASCII characters, with no delimiters between fields or between records.

  • Character 100 (index 99) of every record is a single digit giving the record's type, matching the RECORDTYPE enum in questdefs.h:

    Digit Type Meaning
    1 REC_CONTROL Control record — always record #0
    2 REC_TEXT A block of on-screen text
    3 REC_PLACE A location and its moves/exits
    4 REC_ARTEFACT An object and the actions that can be done with it
    5 REC_GREMLIN A creature and its behaviour
    6 REC_CONDITION A puzzle/logic test
    7 REC_KEYS A block of vocabulary keywords
    8 REC_STATE State-initialisation instructions run at game start
    other — Unused / free / never-allocated record slot
  • The remaining 99 characters are that record's fields, packed back to back in the order given by the matching struct in questdefs.h.

  • A game can span two files (ADATA1 then ADATA2); record numbers are global — once you run past the last record in ADATA1 you continue into ADATA2.

Field widths used to split those 99 characters, derived from questdefs.h's own helper macros (NUM reads a 2-digit number, RECNUM reads a 4-digit number) and verified against sample data:

C type On-disk width Notes
RELREC (record pointer) 4 characters e.g. 0220 → record 220
short 2 characters
char 1 character
char[N] word N‑1 characters Last byte is the C string terminator, not stored on disk
ACTION (flag + data) 6 characters 2-digit flag + 4-character data
MOVE (in a move list) 8 characters 1-char type + 4-char target + 3-char action code

TEXT and PLACE records match these widths exactly against the sample files (confirmed via two clean 49-character text blocks, and real place moves that decode to valid in-range record numbers with literal command words). ARTEFACT, GREMLIN, CONDITION, KEYS and STATE records use the same conventions for consistency but haven't been individually verified byte-for-byte — see Known limitations.

A full field-by-field breakdown of every record type is documented in Quest_Data_Format_Documentation.docx (included alongside this viewer). questdefs.h and that document are the authoritative reference for what each field means; this README just summarises the on-disk layout.

Features

  • Single-record view — one record at a time, laid out as a table of named fields rather than a wall of raw text.
  • Automatic record-type detection — reads character 100 and displays the correct field layout for that record type.
  • Dual-file support — load ADATA1 and ADATA2 together and navigate them as one continuous, globally-numbered set of records. Scrolling forwards or backwards across the boundary between the two files is handled automatically.
  • Field descriptions on hover — hover over any field name to see a tooltip explaining what it means (sourced from questdefs.h).
  • Jump to a referenced record — double-click a value that contains a record number (e.g. a place's text pointer, or a move's target) to jump straight to that record.
  • Back navigation — retrace your steps through jumps with a Back button (or Alt+Left).
  • Go to record # — type a record number and jump directly to it.
  • Plain-text search — find the next record containing a given string, searching across both files.
  • No unparsed data is ever hidden — if a record type's known fields don't consume all 99 characters, the remainder is shown in an "Unparsed / extra data" row instead of being silently dropped.

Requirements

  • Python 3.8+
  • Tkinter (Python's standard GUI toolkit)

No third-party/pip packages are required — the viewer only uses Python's standard library.

Tkinter ships with the standard Python installer on Windows and macOS. On Linux it's often a separate OS package:

Platform How to get Tkinter
Windows / macOS (python.org installer) Included by default
Ubuntu / Debian sudo apt install python3-tk
Fedora sudo dnf install python3-tkinter
Arch sudo pacman -S tk

To check whether it's already available:

python3 -c "import tkinter; print('Tkinter OK')"

Installation

  1. Clone or download this repository:

    git clone https://github.com/<your-username>/<your-repo>.git
    cd <your-repo>
  2. Make sure Python 3 and Tkinter are installed (see Requirements above).

  3. That's it — there's nothing to pip install.

Usage

Run the viewer and pass one or both data files as arguments:

python3 quest_viewer.py ADATA1 ADATA2

You can also start it with no arguments and load files from the GUI:

python3 quest_viewer.py

Then use File > Open ADATA1 (file 1)... and File > Open ADATA2 (file 2)....

Navigating

Action How
Next / previous record Next ▷ / ◁ Prev buttons, or Page Up / Page Down
Jump to the first / last record ⏮ First / Last ⏭
Jump to a specific record number Type it into Go to record # and press Enter (or click Go)
Jump to a record another field points to Double-click that field's value
Return to where you jumped from ◁ Back button, or Alt+Left
Search for text Type into Find and press Enter (or click Find next)
See what a field means Hover the mouse over its name

Record numbers are global: if you go to record 2600 and ADATA1 only has 2,501 records, the viewer automatically shows record 99 of ADATA2 (2600 − 2501). Scrolling with Next/Prev crosses this boundary automatically in both directions.

How the viewer decodes a record

For each record it:

  1. Works out which file and local record index a global record number maps to.
  2. Reads that record's 100 characters and looks at character 100 to determine the record type.
  3. Looks up the field list for that type (defined in quest_viewer.py, matching questdefs.h) and slices the first 99 characters into fields in order, using the widths described above.
  4. Displays each field with its name and current value; hovering a field name shows its description; any left-over or missing bytes are called out explicitly rather than guessed at or hidden.

Known limitations

  • No delimiters exist in the file format, so field boundaries are inferred from questdefs.h's macros and cross-checked against sample data rather than being self-describing. TEXT and PLACE records have been validated closely; other record types use the same conventions but may not be byte-perfect for every field, especially towards the end of longer records (e.g. ARTEFACT, GREMLIN).
  • The control record (record #0) appears to contain additional data not described in questdefs.h (e.g. what looks like a game title and some extra counters) — the fields that are defined decode correctly, and everything after them is shown as raw "Unparsed / extra data" rather than being misrepresented as something it isn't.
  • The viewer treats any record whose type digit doesn't match 1-8 as an unused/free slot and shows its raw content only.
  • This is a read-only viewer — it does not edit or write back to the data files.

If you can independently confirm or correct any field widths (for example by cross-referencing against the original Quest engine source or a known-good save), the field tables near the top of quest_viewer.py are the place to adjust them.

Project structure

.
├── quest_viewer.py                          # the viewer application
├── Quest_Data_Format_Documentation.docx     # full field-by-field reference (from questdefs.h)
├── questdefs.h                              # original C header defining the record structures
└── README.md

License

Add whatever license you'd like this project distributed under (e.g. MIT) here. questdefs.h itself is Copyright © Brendan Murray, 1992-2023, all rights reserved — check with the original author before redistributing it or the game data files.

About

A desktop GUI tool for browsing and inspecting the record-based game database files (`ADATA1`, `ADATA2`) used by the **Quest** text-adventure engine

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages