Ultima IX internal formats

From Ultima Codex
Jump to navigation Jump to search

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 various contributors and the Forgotten World Team.

Definitions[edit]

These are definitions for byte formats used on 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.
  • cstringz - A uint32 string length followed by that many chars, with a NUL (code 0) character as the last character.
  • float32 - A 32-bit floating point value in IEEE-754's binary32 format, in little-endian byte order; this is the same floating-point format used natively on X86 machines.
  • 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[edit]

This is a hierarchical index of the files in Ultima IX 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 is in a MPEG (MPG) sequence, v1, system multiplex, video format.
  • 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[edit]

This is an archive file used extensively throughout the game. The header for each flx files contains records throughout the file for what are essentially subfiles.

Header format[edit]

Offset Length Format Name Description
00h 4Ch text Optional comment; always blank.
4Ch 4 uint32
50h 4 uint32 count Number of entries.
54h 4 uint32
58h 4 uint32 size Total file size.
5Ch 4 uint32 size2 Also total file size.
60h 20h ?? ??
80h 8n dir. List of directory entries, as below.
x x data Actual data.

Directory entry format[edit]

Offset Length Format Description
0 4 uint32 Offset of the record from the start of the file, or 0 if there is no record in this entry.
4 4 uint32 Length of the record in bytes.

Map Files[edit]

Terrain files[edit]

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, which are 8x8 world coordinates each. 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:

Offset Length Format Name Description
00h 4 uint32 width Width in tiles of the region.
04h 4 uint32 height Height in tiles of the region.
08h 80h charz name Name of the region. This appears to only be used for internal purposes.
88h 4 uint32 waterlevel
8Ch 4 uint32 waveamplitude
90h 4 uint32 flags
94h 4 uint32 chunkCount The number of chunks.

This is followed by the tile indices into the chunks:

Offset Length Format Name Description
00h 2*width*height uint16 indices Index of the chunk for each tile, in [x + y * width] order.

The chunk data itself then follows:

Offset Length Format Name Description
00h 4*16*16 uint32 points Points in the chunk.

Each tile is a bitmask with the following format:

First bit Last bit Bits Mask Name Description
0 11 12 4095 height Height of the point, between 0 and 4095 (realistically much less). Each value is 0.25 world coordinates.
12 12 1 1 hole If this is set, this quadrangle should be removed when the terrain is viewed at maximum detail, and it should not impede movement.
13 13 1 1 swap Swap the X and Y axes for the texture coordinates.
14 14 1 1 mirror Mirror the X and Y axes for the texture coordinates.
15 15 1 1 ??
16 21 5 31 frame The index of the frame within the texture to use.
22 31 10 1023 texture The index of the texture to use in the "static/bitmaps8.flx" or "static/bitmaps16.flx" files. Texture index 29 is used but cannot be visible, so it can safely be discarded even if the point is not a hole.

Fixed Files[edit]

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:

Offset Length Format Name Description
00h 4 uint32 ??
04h 4 uint32 ??
08h 4 uint32 pagesSize The size in bytes of all the pages.
0Ch 4 uint32 ??
10h 4 uint32 width The number of tiles the region is wide. This is the same as the terrain height map's width divided by two.
14h 4 uint32 height The number of tiles the region is tall. This is the same as the terrain height map's height divided by two.
18h 4 uint32 ??
1Ch 4 uint32 ??

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

Offset Length Format Name Description
00h 4*width*height uint32 ?? These are either 0 or a number in the form nnnn001h, where nnnn is a number that may be a page index. This may be in [x + y * width] order, but that doesn't seem to corroborate with where objects are located in the maps.

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

Offset Length Format Name Description
000h 4 × 3 uint32 ??
00Ch 4 uint32 baseX The base X coordinate to add to the X coordinate of all objects in the page. This is divisible by 4096.
010h 4 uint32 baseY The base Y coordinate to add to the Y coordinate of all objects in the page. This is divisible by 4096.
014h 4 × 13h (19) uint32 ??
060h 18h × A6h (24 × 166) Fixed object objects The list of objects in the page.
FF0h 10h zero Padding to a 1000h (4096)-byte boundary.

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

Offset Length Format Name Description
00h 4 uint32 reference A byte offset from the start of the file to another object, or 0. Some objects have invalid references, and some are circular.
04h 2*3 uint16 position The location of the object within the tile, between 0 and 4095. This means that for each terrain quad there are 128 discrete positions.
0Ah 2 uint16 type The type index.
0Ch 2*3 int16 angle Angle of the fixed stored in 0.16 fixed point as a conjugated normalized quaternion. This means that to convert to a regular quaternion, if we consider the input values x, y, z, and w, then you compute the angle as Quaternion(-x / 32767.0, -y / 32767.0, -z / 32767.0, w / 32767.0).
12h 2 uint16 Flags Flags for the object.
14h 4 uint32 ?

The flags have these known values:


First bit Last bit Bits Mask Name Description
0 0 1 1 Required Crashes the game if this is not set.
1 1 1 1 CollideWithPlayer Collide with the player, and maybe other NPCs.
12 12 1 1 Semitransparent Render the object as semi-transparent.

Nonfixed Files[edit]

This is the format for the "runtime/nonfixed.%d" files, where %d is between 0 and 239 with some gaps for nonexistent regions. This holds dynamic objects whose state can change. This is the format of the header:

Offset Length Format Name Description
00h 4 × 5 uint32 ??
14h 4 uint32 Width Width of the region in chunks.
18h 4 uint32 Height Height of the region in chunks.
1Ch 4 uint32 ??
20h Width × Height × 4 uint32 Byte offset of the first page in the chunk, relative to the end of the header.
?? 4 uint32 ??

This is then followed by the pages. Each starts with the following header, which is 60h/96 bytes long:

Offset Length Format Name Description
00h 4 uint32 nextPage Offset of the next page in this chunk, relative to the end of the header minus 1, or 0 for none.
04h 4 uint32 endEntityOffset
08h 4 uint32 endTriggerOffset
0Ch 4 uint32 baseX Base X coordinate of the chunk.
10h 4 uint32 baseY Base Y coordinate of the chunk.
14h 4 uint32 entityCount Number of entities in the chunk.
18h 4 uint32 triggerCount Number of triggers in the chunk.
1Ch 4 × 17 uint32 Further offsets to either entities or extra data. (It's not currently clear how to distinguish them.)

This is then followed by entityCount entities:

Offset Length Format Name Description
00h 2 uint16 nextEntitiy Offset to the next entity in a linked list.
02h 2 uint16 ??
04h 2 uint16 offsetX X offset of the entity relative to the chunk's baseX value.
06h 2 uint16 offsetY Y offset of the entity relative to the chunk's baseY value.
08h 2 uint16 z Z position of the entity; the elevation.
0Ah 2 uint16 typeIndex Type index.
0Ch 2 × 4 int16 rotation Rotation of the entity expressed as an 0.16 quaternion (divide integer values by 32767).
14h 4 uint32 flags Entity flags.
18h 2 uint16 meshIndex The mesh index to render for this entity.
1Ah 2 uint16 triggerId
1Ch 4 uint32 extraDataOffset Offset of the extra data, relative to the end of the file header.

If extraDataOffset is not zero, extra data is present at the given relative offset. It has this format:

Offset Length Format Name Description
00h 1 byte argCount Number of parameters in this structure.
01h 3 x 1 byte arguments First, second, and third parameter type (or 0 for none). For example, 66 indicates scaling across all axes.
04h 3 x 4 uint32 values Arguments for each of the 1-3 parameters indicated above. For example, for scaling, this is the scaling factor.

Graphics Files[edit]

The following sub-sections contain the record formats for graphics related FLX files along the file formats for other graphics based files.

Palette files[edit]

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

Offset Length Format Name Description
0 256*4 uint32 palette 256 colors, each using the format below.

Each color has the following format:

Offset Length Format Name Description
0 1 uint8 blue Blue component, from 0 (black) to 255 (most intense).
1 1 uint8 green Green component, from 0 (black) to 255 (most intense).
2 1 uint8 red Red component, from 0 (black) to 255 (most intense).
3 1 uint8 zero Must be zero.

Texture8 FLX record format[edit]

This is the format for the items in the texture8.* files.

NOTE: len is the length of the item

Header[edit]

Offset Length Format Description
0 4 uint32 width
4 4 uint32 height
8 ?? ?? ??
len-width*height width*height data image data, each byte indexes a palette entry in ankh.pal

Bitmap Format[edit]

Header[edit]

Offset Length Format Name Description
00h 2 uint16 width Maximum width in pixels of all frames.
02h 2 uint16 Possibly format-related.
04h 2 uint16 height Maximum height in pixels of all frames.
06h 2 uint16 compression 0 = uncompressed, 1 = 8-bit compression of some sort.
08h 4 uint32 frameCount Number of frames.
0Ch 3 ?? ??
0Fh 1 uint8 frameCount - 1
10h 8frm Frame Record Offset and length for each frame.

Frame Record[edit]

Offset Length Format Description
0 4 uint32 Offset of the frame from the beginning of the file.
4 4 uint32 Length of the frame in bytes.

Frame[edit]

Offset Length Format Name Description
00h 4 uint16 ?? The second uint16 is usually 6000h.
04h 4 uint32 width Width in pixels of this frame.
08h 4 uint32 height Height in pixels of this frame.
0Ch 8 uint32 ?? Both almost always zero.
14h 4*height uint32 rowOffsets Table of 'height' 4-byte entries (offset table of some kind, probably for speed).
x width*height*depth ?? Bitmap data.
x ? ? Mipmaps.

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:

First bit Last bit Bits Mask Name Description
0 4 5 31 red Red component, with 0 as black and 31 as most intense.
5 9 5 31 green Green component, with 0 as black and 31 as most intense.
10 14 5 31 blue Blue component, with 0 as black and 31 as most intense.
15 15 1 1 alpha If set, the pixel is opaque; otherwise it is transparent.

Sappear FLX record format[edit]

This is used for "static/sappear.flx". It defines the 3D meshes, aside from the terrain. Each record begins with this header:

Offset Length Format Name Description
00h 4 uint32 Submesh Count Number of submeshes.
04h 4 uint32 LOD Count Number of level-of-detail stages.
08h 12 vec3 Cylinder Base Centre Centre of the Cylinder Base.
14h 4 float32 Cylinder Base Height The height of the Cylinder
18h 4 float32 Cylinder Base Radius The radius of the Cylinder.
1Ch 12 vec3 Sphere Center Center of Sphere
28h 4 float32 Sphere Radius Radius of the Sphere
2Ch 4 float32 ?? ??
30h 12 vec3 Minimum Bounds Minimum bounds of a bounding box for the mesh.
3Ch 12 vec3 Maximum Bounds Maximum bounds of a bounding box for the mesh.
48h 4 uint32 LOD Threshold 0 Thresholds 0
4Ch 4 uint32 LOD Threshold 1 Thresholds 1
50h 4 uint32 LOD Threshold 2 Thresholds 2
54h 4 uint32 LOD Threshold 3 Thresholds 3
58h 12 vec3 Center of Mass Center of Mass
64h 4 float32 Mass or Volume? ??
68h 36 matrix Inertia Matrix Matrix for the inertia for the model
8Ch 4 float32 Inertia related? Usually 1 or close to zero.
90h 4 × meshCount × lodCount uint32 Submesh Map Offsets from the start of the record for each submesh in (lod + mesh * lodCount) order.

Submesh format[edit]

At each submesh offset is a submesh header:

Offset Length Format Name Description
00h 4 uint32 Limb ID The ID of this submesh
04h 4 uint32 Parent ID The ID of the parent mesh
08h 4 uint32 Scale X Scale of the submesh in the X direction
0Ch 4 uint32 Scale Y Scale of the submesh in the Y direction
10h 4 uint32 Scale Z Scale of the submesh in the Z direction
14h 12 vec3 Position Position/Offset coordinates to parent mesh
18h 4 float32 Orientation W Rotation Scalar
1Ch 4 float32 Orientation X Rotation X
20h 4 float32 Orientation Y Rotation Y
24h 4 float32 Orientation Z Rotation Z

Following the header are the LOD levels.

Offset Length Format Name Description
00h 4 uint32 Mesh Size The size of the submesh in bytes, excluding this value, or 0 if there is no such submesh at this LOD level.
04h 4 uint32 Flags Appears to be a bitmask, with 4 and 8 being most common.
08h 4 uint32 Unused?
0Ch 12 vec3 Sphere Center LOD level's sphere center
18h 4 float Sphere Radius LOD level's sphere radius
1Ch 12 vec3 Minimum Bounds Minimum bounding box.
28h 12 vec3 Maximum Bounds Maximum bounding box.
34h 4 uint32 ignorable
38h 4 uint32 ignorable
3Ch 4 uint32 Face Count Number of faces in the submesh.
40h 4 uint32 Mount Face Count
44h 4 uint32 Vertex Count Number of vertices in the submesh.
48h 4 uint32 Mount Vertex Count
4Ch 4 uint32 Max Face Count
50h 4 uint32 Material Count Number of materials.
54h 4 uint32 Face Offset Offset of the faces relative to the start of the detail level plus 4.
58h 4 uint32 Mount Face Offset
5Ch 4 uint32 Vertex Count Offset of the vertices relative to the start of the detail level plus 4.
60h 4 uint32 Mount Vertex Count
64h 20 uint32 Material Offset Offset of the materials relative to the start of the detail level plus 4.
68h 16 uint32 Sorted Faces Offset
78h 8 uint32 probably unused
Face Offset + 4 7Ch × Face Count Face Faces The list of faces.
Vertex Offset + 4 0Ch × Vertex Count vec3 Vertices The list of vertices.
Material Offset + 4 18h × Material Count Material Materials The list of materials.
Sorted Faces Offset + 4 × Faces Count

Face format[edit]

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

Offset Length Format Name Description
00h 1Ch × 3 point Points Points in the face, described below.
54h 4 bits[32] Flags only first 12 bits appear to be used
58h 4 bits[32] Flags2 unused?
60h 12 (0Ch) vec3 Normal Vector
6Ch 4 float32 Vector W?
6Ch 4 uint32 Material Sometimes a zero-based index into the bitmap16.flx/bitmapC.flx/bitmapsh.flx file (whichever is the active option) for the texture to use. In other cases this has a pattern but no strict correlation to the material. Use the material list instead to select textures.
70h 4 uint8[4] color Color of the face in RGBA order, each element being between 0 (black/transparent) and 255 (bright/opaque).
74h 4 × 2 (8) uint8[8] Collision Related for collision system (index list [so only values from 0, 1, or 2] that contains the index of the vertex that is closest to each of the faces [order is: left,right,front,back,bottom,top]

Point format[edit]

This is the format for a point in a face, which is 1Ch (28) bytes long:

Offset Length Format Name Description
00h 4 uint32 Point Point index.
04h 4 uint32 Point Offset Offset to the point in bytes.
08h 12 vec3 Normal Not always a unit vector.
14h 8 vec2 UV Coordinates UV coordinates.

Material format[edit]

This is the format for a material that is applied to a set of triangles. Each is 18h (24) bytes long:

Offset Length Format Name Description
00h 2 uint16 Texture ID Zero-based index of the texture to use from the bitmap16.flx/bitmapC.flx/bitmapsh.flx file (whichever is the active option).
02h 2 bits[16] Flags
04h 2 uint16 Subtexture Count
06h 2 bits[16] Flags2
08h 2 uint16 First Face ID Zero-based index of the first face with this material.
0Ah 2 uint16 Face Count The number of faces with this material.
0Ch 1 uint8 Default Alpha
0Dh 1 uint8 Modified Alpha
0Eh 1 uint8 Animation Start Starting Frame for animation
0Fh 1 uint8 Animation End Ending Frame for animation
10h 1 uint8 CurFrame
11h 1 uint8 Animation Speed Speed of animation in frames per second
12h 1 uint8 Animation type
13h 1 uint8 Playback direction 0 - forward, 1 - backward
14h 4 uint32 Animation Timer related Animation timer value

Animation FLX record format[edit]

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

Offset Length Format Name Description
00h 4 uint32 index Same as the record index.
04h 8 uint32 ??
08h 4 uint32 totalFrameCount The maximum number of frames.
0Ch 8 uint32 ?? Always [1Eh, 21H].
10h 4 + filename.length cstringz filename The source filename.
14h + filename.length = 0 4 uint32 headerLength The number of elements in the header.
04h 4 × headerLength uint32 ?? The start appears to be repeats of part ids.
04h + 4 × headerLength = 0 4 uint32 partCount The number of parts in the animation.
04h varies part parts The list of parts.
04h + varies = 0 4 uint32 suffixCount The number of suffixes.
04h 4 × 3 × suffixCount uint32 suffixes The list of suffixes, each of which is a uint32 triple. These may be segments of the animation.

Parts for the Animation FLX record format[edit]

This is the format of a part.

Offset Length Format Name Description
00h 4 uint32 id A one-based identifier of the part. This corresponds to a limb ID from the mesh. Values above 255 appear to be unrelated parts from the LightWave file (such as the camera and light rigging).
04h 4 + name.length cstringz name Length-prefixed name of the part.
08h + name.length = 0 4 uint32 frameCount Number of frames.
04h 2Ch (44) × frameCount frame frames List of frames.

Frames for the Animation FLX record format[edit]

This is the format of a frame within a part. The transformation replaces the transformation of the corresponding mesh when this frame is active.

Offset Length Format Name Description
00h 4 uint32 ms The number of milliseconds from the start of the animation to display this frame for this part.
10h 4 × 4 float32 rotation Rotation quaternion, this time given in the order W, X, Y, Z.
04h Ch (12) vec3 position The relative transform for positioning the part.
20h Ch (12) vec3 scale The scaling factor.

Item Files[edit]

Types Database File[edit]

Offset Length Format Name Description
00h 4 uint32 ?? Either 0 or CDCDCDCDh, with no apparent reason.
04h 2 uint16 Usecode ID Refers to an entry in the usecode list, which is within the game engine.
06h 2 uint16 Default Model ID Refers to a model entry in the "static/sappear.flx". This model ID is used by default but the model ID used per instance in the nonfixed map file takes priority.
08h 2 bits Type Flags Each bit of this word is a separate type flag: Never Hidden(0x01), NPC Only Collision(0x02), Partial Collision(0x04), Non Camera Block (see Spaces FLX)(0x08),

Portal Block (see Spaces FLX)(0x10), Unique Model (Final Art I'm guessing for the modelers)(0x20), ??(0x40), Not used, Vestigial(0x80), Mesh Collision(0x0100)

0Ah 1 uint8 Object Weight Weight used for Physics gravity, FF are not player movable, FE appears to be the same
0Bh 1 uint8 Volume Probably used for collision cylinder
0Ch 1 uint8 Book Number Vestigial parameter, may not even be recognized by the engine.
0Dh 1 uint8 Hitpoints Vestigial parameter, handled with NPC.flx or type's instance nonfixed property.
0Eh 2 uint16 ?? Always 0.

Type name FLX record format[edit]

This is the record type used in "static/typename.flx". This includes the tooltip icon and text used with the inventory and examine features in the game. Each typename entry corresponds to an object type in "static/types.dat".

Offset Length Format Name Description
00h 4 uint32 ?? Either 0, -1, or rarely a value above 255. Possibly script-related.
04h 2 uint16 Icon ID Inventory Icon ID for an image in "static/bitmaps16.flx" or "static/bitmaps8.flx".
06h - charz Tooltip Text Tooltip for the type. Null-terminated text.

Book FLX record format[edit]

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.

Offset Length Format Description
0 4+ cstringz Title string in the form "(id number): (book title)". This doesn't appear to be used.
x 4+ cstring Book text body.

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.

Text and MiscText FLX record format[edit]

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.

NPC FLX record format[edit]

Each record is 143h/323 bytes in size.

Offset Length Format Name Description
000h 4 ?? ?? ??
004h 32 charz[32] Name Name of the NPC.
024h 1 uint8 Gender 0: Male, 1: Female.
025h 15 ?? ?? ??
034h 2 uint16 HealthCurrent Current health.
036h 2 uint16 HealthMaximum Maximum health.
038h 2 uint16 HealthMaximum2 Also maximum health.
03Ah 2 uint16 ManaCurrent Current mana.
03Ch 2 uint16 ManaMaximum Maximum mana.
03Eh 2 uint16 ManaMaximum2 Also maximum mana.
040h 24 ?? ?? ??
058h 4 uint32 Region Region index the NPC is in.
05Ch 4 uint32 PositionX X coordinate of the NPC.
060h 4 uint32 PositionY Y coordinate of the NPC.
064h 2 uint16 PositionZ Z coordinate of the NPC (elevation).
068h 4 ?? ?? ??
06Ch 1 uint8 ScaleX X scale in percent.
06Dh 1 uint8 ScaleY Y scale in percent.
06Eh 1 uint8 ScaleZ Z scale in percent.
06Fh 212 ?? ?? ??

Scripting Files[edit]

Activity FLX record format[edit]

Triggers FLX record format[edit]

Highway Database record format[edit]

Offset Length Format Name Description
00h 4 uint32 Number of Highway Points Number of Highway Points in file
04h 4 uint32 Number of Highway Segments Number of Highway Segments in file


Following the header are a bunch of highway points, which define the location of cross objects (patheggs in the U7 vernacular). Each Highway point has the following format.

Offset Length Format Name Description
00h 4 uint32 Trigger ID Trigger ID for a highway pathegg.
04h 4 uint32 X coordinate Absolute X coordinate of the map for the corresponding highway pathegg.
08h 4 uint32 Y coordinate Absolute Y coordinate of the map for the corresponding highway pathegg.


Following the highway points is a unint32 containing the total number of bytes for the highway segments. After that are the highway segments, which have the following format.

Offset Length Format Name Description
00h 2 uint16 Start Trigger ID Trigger ID for the first highway pathegg.
02h 2 uint16 Last Trigger ID Trigger ID for the last highway pathegg.
04h 2 uint16 Path Length Number of highway points in segment.
06h 2 uint16 Route Distance Total distance to travel for route.
08h 2 uint16 Nulls part of distance or unused bytes

Following each highway segment is a sequence of uint16's that define the exact route of highway point trigger IDs.

Sound Files[edit]

Sound FLX record format[edit]

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.

Offset Length Format Name Description
00h 4 uint32 id Identification number.
04h 20h asciiz description Description.
24h 4 ? probably more description?
28h 4 uint32 length Sample data length in bytes.
2Ch 4 uint32 frequency Frequency in hertz.
30h 4 uint32 Bits per sample?
34h 4 uint32 Channel count?
38h 4 uint32 encoding Encoding method; see below.
3Ch length x data Sample data, in the encoding method.

These are the encoding methods:

Value Meaning
0 PCM (ie. no compression/encoding)
1 ADPCM
2 EA MicroTalk - used by speech

Miscellaneous Files[edit]

Savegame files[edit]

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:

Header[edit]

The Header contains the Start.dat file, the title of the savegame, possibly some current camera data, and a low-res screenshot for the savegame.

Offset Length Format Name Description
00h 6 char magic Always "U9:008".
06h 4 uint32 Savegame Number Null Field to record the savegame number for the Start.dat file used by the engine to determine, which savegame was last loaded.
0Ah 4 uint32 description.length Length of Savegame title
0Eh description.length cstringz Savegame Title The title input into the save game dialog.
0Eh + description.length 25h ?? ?? Could be data for the camera's position and properties
33h + description.length 4 uint32 Map Number Map number for player's location for that savegame
37h + description.length 23h ?? ?? More data for the camera's position and properties

Game Picture[edit]

Offset Length Format Name Description
00h 4 uint32 width Width of the picture in pixels. This is always 256.
04h 4 uint32 height Height of the picture in pixels. This is always 128.
08h 4 × 2 uint32 ??
10h 4 × height uint32 rowOffsets Appears to be offsets to the rows. This is constant, but the base seems unclear.
10h + 4 × height width × height uint8 pixels Picture data in [x + y * width] order, in 8-bit indexed mode, using "static/ankh.pal" for colors.

Processes Database[edit]

Offset Length Format Name Description
00h 4 uint32 size Size in bytes of the processes data.
04h size ?? ?? Process data. The First part contain variables. Second part starts at 58h/88 is the NPC.flx data.

Diary Text[edit]

Offset Length Format Name Description
00h 4 uint32 diary.length Length of the current Diary in bytes.
04h diary.length cstringz All Diary Entries Each entry in the diary except the last one ends with the byte sequence [0Ah 09h 09h 09h BCh BDh BEh 0Ah], which translates to the formating: ENTER + TAB + TAB + TAB + <Unknown> + ENTER

Nonfixed Files[edit]

The remainder of the file are current state for all encountered nonfixed.# files as of that save.

External Links[edit]

  • 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.

Technical Details
Game Ultima IIIUltima IVUltima VUltima VIUltima VIIUltima VIIIUltima IXUltima Underworld