Ultima IX Internal Formats

=Introduction= Here is a description of various data files used by Ultima IX. This compiles information from the sources given in the links, as well as information discovered by contributors.

=General Types= These types are used in this page:
 * char - An 8-bit (1-byte) character code in Windows-1252 encoding.
 * charz - As with char, but a nul character (code 0) terminates a string.
 * cstring - A uint32 string length followed by that many chars. This is usually NUL-terminated (with no garbage, so the NUL if present is the last character); exceptions are noted.
 * float32 - A 32-bit floating point value in IEEE-754's binary32 format, in little-endian byte order.
 * uint8 - Unsigned 8-bit (1-byte) integer, between 0 and 255 (2^8-1).
 * uint16 - Unsigned 16-bit (2-byte) integer, between 0 and 65535 (2^16-1), in little-endian byte order.
 * uint32 - Unsigned 32-bit (4-byte) integer, between 0 and 4294967295 (2^32-1), in little-endian byte order.
 * vec3 - A 3-D vector stored as three float32 for x, y, and z.

=Files= This is a hierarchical index of the files in Ultima 9 and what is known about them. This assumes that everything is installed from the CD, using a custom install.
 * 00000409.016, 00000409.256 - Installation background images in BMP format. No use to the game.
 * autorun.exe, autorun.ico, eahelp.hlp, FinalSetup.exe, ip.cfg, ip.exe, Uninst.isu - Installation files with no use to the game.
 * clcd16.dll, clcd32.dll, clokspl.exe, ConfigINI.exe, dplayerx.dll, drvmgt.dll, Dsetup.dll, secdrv.sys - Executable files with limited apparent applicability.
 * D3D.TXT, Eula.txt, keymap.new, options.new, OPTIONS.TXT, PATCH.TXT, PERFORM.TXT, Readme.txt - Text files with no use to the game.
 * Default.kmp - Keymap in INI format.
 * Options.ini - Game options in INI format.
 * u9.exe - Main executable.
 * EREG/ - Electronic registration files; no use to the game.
 * Movies/ - The game's movies files in a normal but unknown movie format. Renaming to AVI allows playing in Windows Media Player.
 * runtime/ - Data that can be modified during the game.
 * nonfixed.%d, where %d is between 0 and 239.
 * npc.flx - Contains a single record, which is a list of NPCs. Since "u9game0.sav" appears to be used for initial state and it also has a list of NPCs, it's not clear whether this is used by the game.
 * savegame/ - Save files, as well as what looks to be temporary unpacked files used while playing.
 * savegame/u9game%d.sav, where %d is a number between 1 and infinity - The packed savegames, using the Savegame file format.
 * sound/ - Speech, sound effects, and music files.
 * sound/music.flx
 * sound/sfx.flx
 * sound/sfxassoc.flx
 * sound/sfxcat.flx
 * sound/sfxenv.flx
 * sound/sfxtmpl.flx
 * sound/Speech.flx
 * static/ - Data that cannot be modified during the game.
 * static/activity.flx
 * static/anim.flx - Animations for the NPCs and books, using the Animation FLX record format.
 * static/ankh.pal - Palette used in 8-bit rendering mode and in the pictures in the savegames, using the Palette file format.
 * static/areas.flx
 * static/bitmap16.flx, static/bitmapC.flx, static/bitmapsh.flx
 * static/books-en.flx - Books and stores files, using the Book FLX record format.
 * static/dimension.dat
 * static/fixed.%d, where %d is 0 to 239 - Immovable objects within the region, using the Fixed file format.
 * static/highway.dat
 * static/Mbrk.br, static/Mbrk.fn, static/Mbrk.ns, static/Mbrk.vl
 * static/misctext.flx - Miscellaneous text strings, in the Wide String FLX record format.
 * static/registry.txt - Appears to be a list of bone names and numbers.
 * static/rgbccube.dat, static/shade.tbl, static/shadegry.tbl, static/yiqccube.dat - Used in 8-bit rendering mode.
 * static/sappear.flx - 3D mesh data, in the Mesh FLX record format.
 * static/sdInfo.flx, static/sdInfo16.flx, static/sdInfoC.flx
 * static/spaces.flx
 * static/Tbrk.br, static/Tbrk.fn, static/Tbrk.ns, static/Tbrk.vl
 * static/terrain.%d, where %d is 0 to 239 - Terrain height map information, in the Terrain file format.
 * static/text.dat
 * static/text.flx - Text strings, in the Wide String FLX format.
 * static/Texture8.9, static/Texture8.14, static/texture16.9, static/texture16.14 - Textures where each panel is a 16x16 segment from the terrain for the given region. This may be used for the low-detail terrain rendering.
 * static/Tnbrk.br, static/Tnbrk.fn, static/Tnbrk.ns, static/Tnbrk.vl
 * static/treedat.flx
 * static/triggers.flx
 * static/typename.flx - Type name and icons, in the Type Name FLX format.
 * static/types.dat
 * static/u9game0.sav - Initial save state used when starting a new game, using the Savegame file format.

=FLX Format= This is an archive file used extensively throughout the game. Each record has the same type, which depends upon the filename.

Record Formats
The following sub-sections are the record formats stored within FLX files.

Animation FLX record format
This is used by the "static/anim.flx" file. It contains all the body part animations for the NPCs, and animations for the books.

Parts for the Animation FLX record format
This is the format of a part.

Frames for the Animation FLX record format
This is the format of a frame within a part.

Frame
The "depth" above means the bytes per pixel, which is 1 for "static/bitmaps8.flx" or 2 for "static/bitmaps16.flx". 16-bit pixels use this bitmask:

Book FLX record format
The format for records in "static/books-en.flx" is as follows. This format is more than likely also used for the other languages as well.

The body format depends upon whether this is a book or a store record. A book has significant newlines. A line beginning with ` changes the font, and can be:


 * `p - Apparently the intent is for a new page, but it's always at the beginning of the book.
 * `f1 - Blue font.
 * `f2 - Red font.
 * `f3 - Black italic font.
 * `f5 - Gargish font.

`f4 is not used, but would probably be runic.

Stores have a line-oriented format. The first line is the name of the store. Subsequent lines may begin with "!", indicating that they are a comment. Otherwise they have the form '#(number) "(name)" $(price)', where (number) is the item number, (name) is the name to display (which is adjusted to fit the size of the GUI), and (price) is the price of the item.

Mesh FLX record format
This is used for "static/sappear.flx". It defines the 3D meshes, aside from the terrain. This format is not well-understood; the following will produce incorrect results much of the time. Each record begins with this header:

The header then continues, with what seems to be a submesh object:

Triangle format
Each triangle is 7Ch (124) bytes long, and has this format:

Vertex format
This is the format for a vertex in a triangle, which is 1Ch (28) bytes long:

Sound FLX record format
This is used for "sounds/sfx.flx", "sounds/music.flx", "sounds/speech.flx", maybe others.

The format of the type 1 encoding was determined by Josef Drexler. These are the encoding methods:

Texture8 FLX record format
This is the format for the items in the texture8.* files.

NOTE: len is the length of the item

Type name FLX record format
This is the record type used in "static/typename.flx"; it describes a type of object, as well as its icon.

Wide string FLX record format
This is the format for records in "static/text.flx" and "static/misctext.flx". Each record is a UCS-2 string that is nul-terminated. It is possible, but unlikely, that it is in UTF-16.

=Fixed Files= This is the format for the "static/fixed.%d" files, where %d is between 0 and 239 with some gaps for nonexistent regions. This contains the objects which cannot be moved or interacted with, such as trees or houses. The region is cut into 32x32 point blocks. The format of the block is not known, but they somehow map to pages, which store a sequence of fixed objects. This is the format of the header:

This is followed by some kind of value related to the tiles:

The pages themselves follow. Each is 1000h (4096) bytes long:

The fixed objects are 18h (24) bytes long:

=Palette files= This is used with "static/ankh.pal", which is the master palette used in 8-bit mode and for the pictures in savegames.

Each color has the following format:

=Savegame files= This is used with the "savegame/u9game%d.sav" files, as well as "static/u9game0.sav". These contain packed savegame data. This is the basic format:

The game picture then follows.

The processes data - which includes the NPCs - then follows:

This is followed by the diary and some unknown fields:

The remainder of the file is undecoded.

=Terrain files= This is the format for the "static/terrain.%d" files, where %d is between 0 and 239 with some gaps for nonexistent regions. This contains the height map information for that region, and is present even if the region doesn't have any visible terrain. The terrain is cut into 16x16 point tiles. Each tile refers to a chunk, and it is possible for a chunk to be used by multiple tiles (such as if it's the bottom of the ocean). Curiously, there are always more chunks than tiles. This is the format of the header:

This is followed by the tile indices into the chunks:

The chunk data itself then follows:

Each point is a bitmask with the following format:

=External Links=
 * U9Tools - a collection of tools that allow the user to extract and modify the contents of various Ultima IX data files.
 * U9Decode - Joseph Drexler's utility that allows the user to extract Ultima IX's music.
 * Paeron - Paeron's documentation, supplementing information from Tumbleweed.