HeroQuest (MS-DOS, Gremlin Graphics, 1991–92) — measurements of an 827,419-byte installed game directory: what the eighty-four files are, how they are built, and the code that reproduces every figure.
No porting, no reverse-engineering toward a re-release, no assets. This is a description of one game's files and the commands that produced the numbers.
→ Start at docs/00-predictions.md, written before a single file inside the archive was opened, and docs/13-prediction-scoring.md, which scores it four hits, four misses and three mixed. The misses are the best pages here.
The second game in the series is documented on a different machine two years later at cd32-heroquest2-doc. Same publisher, same licensed board game, MS-DOS 1992 against Amiga CD32 1994. docs/11-vs-heroquest2.md is the comparison, and four of its five points come out against continuity.
There is no shared checklist for the PC in this collection and there should not be: "PC" spans thirty years and a DOS floppy game and a modern remaster have nothing in common but the machine they end up on. Everything platform-level therefore stays in this repository, written out in full rather than referenced.
QUEST.SAV is stamped 1998-09-04, six years after every other file, and
holds a roster of characters somebody named. The ZIP around it is from 2008. So
this is somebody's installed game directory zipped up sixteen years later,
not an image of the shipped medium — and the one file the executables name that
is missing, QUEST.CFG, says the directory was curated rather than dumped.
That is not fatal, and it is measurable rather than merely disclaimed: the
installer is in the archive and contains exactly one file-creating operation,
copy %1:*.*, which preserves write dates. So the 1991–92 timestamps are
Gremlin's own. Every statement here is a statement about this copy; said
once, in docs/01-archive-and-provenance.md,
and then not repeated.
1. All three executables are packed, with Microsoft EXEPACK, and only one of
them is stamped 1980. QUEST.EXE carries 1980-01-06 19:48:46 — six days
and nineteen hours past the MS-DOS epoch, 0x0026/0x9E17 — while
INTRO.EXE and HERO.EXE carry perfectly ordinary 1992-02-05 dates. The three
share 283 bytes of identical decompressor stub, so the packer cannot be the
cause. The ZIP is eliminated too: the local file header and the central
directory agree on all 84 entries with zero mismatches. The shared CD32
checklist has carried a "sixth epoch" hypothesis for months and this is its
first DOS sample; the answer it gets is file, not chain.
2. The complete HeroQuest board, reconstructed from twenty-four masks. Each
quest file opens with a 26 × 19 byte grid of region ids. Every square is either
0 or one fixed id, so the union across all twenty-four files rebuilds the whole
board: 42 regions, 494 squares, zero unassigned. Twenty of the regions are
the corridor ring and cross passages; twenty-two are the rooms. A second
26 × 19 grid at offset 512 holds the walls — 0x80 north, 0x40 west — with
each layer padded up to a 512-byte boundary. The two grids are 54 % of a quest
file.
3. Accented letters are remapped onto the lower-case ASCII row. The game
ships an 87-glyph bitmap font covering 0x20–0x76 with no lower case at all,
and 0x61–0x76 hold the accents instead: a = Ä, e = È, n = Ñ, o = Ö,
u = Ü, and more. Confirmed three ways — the glyph bitmaps, a per-language
literal census, and uncompressed German text reading STEINJaGER, HuGELGRAB
and HAUPTMENu. Seven of the twenty-three glyphs in that row are byte-identical
copies of G–M, which is how you can tell the row was allocated as a block
and only the positions that needed an accent were redrawn.
4. The CD32 sequel remaps accents onto ( ) * + and this game does not, and
the reason is visible in the fonts. HeroQuest II's font includes lower case,
so that row was taken and only four punctuation slots were left — which is why
it has four accented glyphs and three languages, and this game has up to
twenty-three and five. Same instinct, independently reinvented, and the second
game's version is the worse one.
5. Five languages, and English-only prose. 297 interface strings per
language, all five files built on 1992-02-12 between 15:38:16 and 15:48:14
— nine minutes and fifty-eight seconds. The twenty-four quest titles are
localised too, five times over, in EQUESTS.BIN. But the twenty-four quest
briefings — 8,500 characters — sit inside QUEST1.BIN..QUEST24.BIN in
plain uppercase English, and there is only one set. So the game is multilingual
in its interface and monolingual in its narrative. The archive's filename says
_EN; it is half wrong and half right.
6. The licence is in plain text, which makes the sequel the anomaly. The
same scan that finds no Hasbro string anywhere on the CD32 disc finds this in
INTRO.EXE, drawn with the game's own font:
HERO QUEST COPYRIGHT 1991
HASBRO BRADLEY LIMITED IN
ASSOCIATION WITH GAMES WORKSHOP
COMPUTER SOFTWARE COPYRIGHT 1991
GREMLIN GRAPHICS LIMITED
and zero occurrences of HASBRO, GAMES WORKSHOP, BRADLEY, MILTON,
GREMLIN or IMAGITEC in any of the forty-two picture files. The pixels-only
notice on CD32 was not a house policy.
7. Imagitec supplied the audio to both games, and the two products disclose it
in opposite ways. On CD32 the name survives only inside a linked replayer that
no screen credits. Here the four audio drivers carry zero attributable strings
in 22,092 bytes and the intro says it out loud: MUSIC AND SFX BY IMAGITEC,
under PROGRAM BY ROGER WOMACK, WITH INTRO BY MARK GLOSSOP, VGA GRAPHICS BY IAN HARLING, EGA GRAPHICS BY TIM MAY. Three of the four drivers predate every
picture in the archive by two months, so the library already existed.
8. The famous 1.945 ratio measures the intro, not the colour depth.
386,904 bytes of .VGA over 198,903 of .EGA is 1.945, temptingly close to
4-bit-versus-8-bit. Restricted to the fifteen names that exist in both forms it
is 1.123, with per-file ratios from 0.640 to 2.544 and four of
fifteen where the VGA file is smaller. The gap is 181,475 bytes of VGA-only
intro art — 21.9 % of the whole game — that EGA and Tandy players never see,
because the title sequence is a VGA-only feature.
9. The two picture sets are two exports of one work list, and the filesystem
proves it. On 1992-01-11 a tool wrote seven EGA pictures between 12:05:06 and
12:16:04 and ten VGA pictures between 20:31:08 and 20:41:00 — in the same
order: MONSTERS, ODDS&SOD, FURN, SHOPSP, then INVENT, SPELLIT.
Thirty-four of the eighty-four files carry that one date, including seventeen
quest files written two seconds apart in a fifty-two-second burst. Seven of the
twenty-four quests were re-exported individually over the following six weeks;
the last file anyone touched was quest 16, The Cold Halls, on 1992-02-21.
10. Manual-lookup copy protection, and its asset is one of the two EGA-only
files. QUEST.EXE holds HEROQUEST PROTECTION / PLEASE CONSULT YOUR HEROQUEST MANUAL / AND ENTER THE PAGE ON WHICH THIS SHIELD / REBOOT AND TRY AGAIN, and names shields.ega 1,197 bytes later. SHIELDS.EGA and
FLAGS.EGA are the only two pictures with no VGA counterpart because they are
drawn in EGA format whatever mode the player chose.
And one that is not a finding but is the best line in the archive: the French
quest index translates Barrow of the Witchlord as BROUETTE DU SORCIER —
wheelbarrow of the sorcerer. It shipped.
python tools/census.py _work/hero-quest
| category | files | bytes | share |
|---|---|---|---|
| graphics, VGA | 25 | 386,904 | 46.76 % |
| graphics, EGA | 17 | 198,903 | 24.04 % |
| executables | 3 | 75,301 | 9.10 % |
| language text | 5 | 50,403 | 6.09 % |
| quests | 25 | 47,165 | 5.70 % |
| audio banks | 2 | 44,320 | 5.36 % |
| audio drivers | 4 | 22,092 | 2.67 % |
| saved game | 1 | 1,376 | 0.17 % |
| batch files | 2 | 955 | 0.12 % |
| total | 84 | 827,419 |
Pictures are 70.80 % of the game and code is 9.10 %, which is the most descriptive single fact about a board game adaptation.
INSTALL A C -> md \HEROQUES, copy disk 1, chain to MG.BAT
MG.BAT -> disk 2 (sentinel QUEST.EXE), disk 3 (sentinel FURN.EGA)
HERO -> HERO.EXE, 304 bytes of assembly, three strings
exec INTRO.EXE config menus, title, credits, story
exec QUEST.EXE copy-protection screen, then the game
| 00-predictions.md | written before the archive was opened, never edited except to add the measurement under each |
| 01-archive-and-provenance.md | what this copy is, the container, the census, the missing QUEST.CFG, the three floppies, and the studio and licensor read from the files |
| 02-timestamps.md | twenty-nine dates, a thirty-four-file day split into three machine runs, a fifty-two-second quest export and a nine-minute localisation |
| 03-the-1980-stamp.md | one file, three suspects eliminated by measurement, and what goes back to the CD32 checklist |
| 04-executables.md | MZ headers, EXEPACK undone, the 1,312-byte library shared by two of the three, and the filename tables that answer two other chapters' questions |
| 05-install-and-copy-protection.md | two batch files read as programs, the shield on page N, and a shipped ECHO is off. |
| 06-language-files.md | 297 strings × 5, a half-decoded codec with the evidence recorded, the accent census, and the prose that was never translated |
| 07-font-and-text.md | 87 glyphs found rather than assumed, twenty-three accents in the lower-case row, seven of them copies of capitals, and two text engines |
| 08-quest-files.md | the board rebuilt from twenty-four masks, the wall layer, the party's 2 × 2 block, twenty-four titles, and a five-language index |
| 09-graphics.md | 1.945 against 1.123, half an opcode space, why two files are EGA-only and ten are VGA-only, and the timestamps that say one source |
| 10-audio.md | four headerless drivers with two entry conventions and no banners, one tracker module holding a tune and nine effects, and which bank is whose |
| 11-vs-heroquest2.md | five falsifiable points against the CD32 sequel; four come out against continuity |
| 12-open-questions.md | ten, each with the measurement it needs and what was already tried and failed |
| 13-prediction-scoring.md | four hits, four misses, three mixed — including one wrong model that scored a hit and a miss on adjacent pages |
| 14-tools.md | what each tool measures, seven scans that returned zero, and the one mistake this EXE format invites |
| 15-leftovers.md | somebody's saved characters, an epilogue, a wheelbarrow, and what to do next in order |
Put HeroQuest_DOS_EN.zip in the repository root — it is not committed — and
run:
mkdir -p _work notes
python -c "import zipfile; zipfile.ZipFile('HeroQuest_DOS_EN.zip').extractall('_work')"
python tools/ziplist.py HeroQuest_DOS_EN.zip > notes/ziplist.txt
python tools/census.py _work/hero-quest > notes/census.txt
python tools/mzinfo.py _work/hero-quest/QUEST.EXE > notes/mz.txt
python tools/exepack.py _work/hero-quest/QUEST.EXE -o _work/QUEST.unp
python tools/exepack.py _work/hero-quest/INTRO.EXE -o _work/INTRO.unp
python tools/exepack.py _work/hero-quest/HERO.EXE -o _work/HERO.unp
python tools/strdump.py _work/QUEST.unp --min 5 > notes/str-exe.txt
python tools/font.py _work/QUEST.unp > notes/font.txt
python tools/lang.py _work/hero-quest --strict --run 6 > notes/lang.txt
python tools/quest.py _work/hero-quest > notes/quest.txt
python tools/gfx.py _work/hero-quest --codec > notes/gfx.txt
python tools/audio.py _work/hero-quest > notes/audio.txt
python tools/sav.py _work/hero-quest/QUEST.SAV > notes/sav.txt
python tools/licence.py _work/hero-quest _work > notes/licence.txt
Plain Python 3, no dependencies, no disassembler, no image library. The saved
output of every one of those runs is in notes/, so every number in
the documents can be checked without having the game.
What is not in this repository: the archive, any extracted file, any executable packed or unpacked, any picture, any sound. Only measurements and the code that makes them.
Every offset quoted for QUEST.EXE, INTRO.EXE or HERO.EXE in the form
0x… is an offset into the unpacked image produced by tools/exepack.py,
not into the file on disk. The font is at 0xC8D3 in QUEST.unp and at 0x13B5 in
INTRO.unp; it is the same 696 bytes. Offsets quoted for data files are file
offsets, because none of them is packed as a whole.