.eng Documented

The ENG text format

All of a game's text lives in .eng files: one for strings, one ending _mm.eng for the pop-up messages, which carries dialog geometry alongside the words. Anyone translating one of these games, or reading its text out, works here.

Used by Caesar III Pharaoh Zeus Emperor

Two related files, both in three parts: a short header, a fixed-size index, and a data section of null-separated strings.

The wiki documents Caesar III as its worked example — its files identify themselves with a descriptor string like "C3 textfile." — and the later titles use the same structure with their own descriptor and their own quirks.

Text file header

28 bytes.

OffsetSizeTypeFieldDescription
016char[]descriptorIdentifies the file and the game, e.g. "C3 textfile."
164int32num_groupsHighest group ID in use, plus one.
204int32num_stringsTotal strings in the file.
244int32num_wordsWord count. Not reliable — do not use it to size a buffer.

Text file index

1,000 entries of 8 bytes each, following the header.

OffsetSizeTypeFieldDescription
04int32offsetWhere this group's strings begin in the data section.
44int32in_useIn the earlier games a flag, 0 or 1. In the later ones, the number of strings in the group.

Text data and encoding

Strings run consecutively, separated by null bytes, and a string must contain at least one printable character — a byte of 32 or above — to count.

There is no encoding declared anywhere in the file; it follows from the language of the release. Western European editions use Windows-1252, Polish uses Windows-1250, Russian Windows-1251, and Korean Windows-950. Traditional Chinese uses an encoding of its own.

Message file header

24 bytes. Message files are the ones whose names end in _mm.eng.

OffsetSizeTypeFieldDescription
016char[]descriptorIdentifies the file, e.g. "C3 MMfile".
164int32num_entriesIndex entries present — typically 1,000.
204int32num_usedHighest index in use, plus one.

Message index entry

80 bytes each. This is where the format stops being a string table: each entry lays out the dialog the message appears in.

OffsetSizeTypeFieldDescription
02int16typeMessage type.
22int16message_typeMessage subtype.
62int16xDialog X position.
82int16yDialog Y position.
102int16width_blocksDialog width, in 16-pixel blocks.
122int16height_blocksDialog height, in 16-pixel blocks.
142int16image1_idPrimary image ID.
162int16image1_xPrimary image X.
182int16image1_yPrimary image Y.
202int16image2_idSecondary image ID.
222int16image2_xSecondary image X.
242int16image2_ySecondary image Y.
262int16title_xTitle X.
282int16title_yTitle Y.
302int16subtitle_xSubtitle X.
322int16subtitle_ySubtitle Y.
382int16video_xVideo X.
402int16video_yVideo Y.
564int32urgent0 for a normal message, 1 for an urgent one.
604int32video_offsetOffset of the video filename string.
644int32unknown_offsetOffset of a string whose purpose is not established.
684int32title_offsetOffset of the title string.
724int32subtitle_offsetOffset of the subtitle string.
764int32content_offsetOffset of the body text, which may contain formatting.

Sources