Ultima VIII Internal Formats

This page deals with the details on the specifications of the file formats for the different files included in Ultima VIII.

Files
These are the files in an Ultima VIII installation, and what is known about them.


 * u8.exe
 * gamedat/ - Contains an unpacked savegame and runtime data.
 * gamedat/avatar.dat
 * gamedat/flag.dat
 * gamedat/gumps.dat
 * gamedat/itemcach.dat - A FLX archive
 * gamedat/kernel.dat - A FLX archive
 * gamedat/nonfixed.dat - A FLX archive containing world objects that can be changed.
 * gamedat/npcdata.dat - A FLX archive
 * savegame/u8save.###
 * sound/
 * sound/*.dll - Music device drivers.
 * sound/music.flx - A FLX archive
 * sound/sound.flx - A FLX archive
 * static/ - Contains unchanging game data.
 * static/anim.dat
 * static/ecredits.dat
 * static/eintro.skf - A FLX archive
 * static/endgame.skf - A FLX archive
 * static/fixed.dat - A FLX archive containing world objects that cannot be changed.
 * static/glob.flx - A FLX archive containing templates used in map data.
 * static/gumpage.dat
 * static/quotes.dat
 * static/typeflag.dat - Contains information about the types in the game.
 * static/u8fonts.flx - A FLX archive containing Shapes that have fonts for the game.
 * static/u8gumps.flx - A FLX archive containing Shapes that have game interface images and gumps.
 * static/u8mouse.shp - A standalone Shape file that has the mouse cursors.
 * static/u8pal.pal - A standalone file that contains the game palette.
 * static/u8shapes.cmp - Compressed form of "static/u8shapes.flx". The first time the game is run, it is decompressed.
 * static/u8shapes.flx - A FLX archive containing Shapes that have world graphics and animations.
 * static/wpnovlav.dat - A FLX archive
 * static/xformpal.dat - A FLX archive
 * usecode/ - Contains game scripting data.
 * usecode/eusecode.flx - A FLX archive
 * usecode/unkcoff.dat

Common Formats
All multi-byte data are stored in little-endian order. For example, 1122h could be stored as the bytes (22h 11h). Signed values are stored as two's-complement. For example, the signed byte -1 is stored as FFh. These are the basic types that are referred to throughout this document:


 * uint8/16/24/32 - Unsigned one, two, three, and four-byte integers.
 * int8/16/32 - Signed one, two, and four-byte integers.
 * char - ASCII character stored as uint8.
 * zero - A single byte that is always zero.

FLX Archives
Files with a ".flx" extension, and many without, are stored in a common archive file format. The header has this format:

The interpretation of record data depends upon the file itself. All records in an archive have the same format.

Palettes
Palettes are stored as (Color[256] Colors), where Color is (uint8 Red, uint8 Green, uint8 Blue), and each component is from 0 (darkest) to 63 (brightest). Index 255 is transparent.

Shapes
Shapes are used as the record format in the FLX Archives "static/u8shapes.flx", "static/u8fonts.flx", and "static/u8gumps.flx" files, as well as a single standalone shape in the "static/u8mouse.shp" file. It has this format:

RowData is stored as RLE data. Describing this is easiest in pseudocode:

int x = 0;

while(x < SizeX) { x += ReadUInt8; if(x >= SizeX) break;

uint8 length = ReadUInt8; uint8 type = 0;

if(Compression == 1) { type = length & 1; length >>= 1; }

// Read length bytes to the output. if(type == 0) ReadData(x, y, length); else { // Copy value length times to the output. uint8 value = ReadUInt8; ReadRun(x, y, length, value); }   x += length; }

File Structure
This section discusses individual files within their subsystem.

Type flags (static/typeflag.dat)
This contains information about each type in the game. Each type info record is 8 bytes long; there are 2048 records in Ultima 8 (one for each entry in "static/u8shapes.shp"). Each record has this bit format:

The AnimationType field changes the conditions where the shape will cycle through a frame during a game update tick, and what frames are cycled through. These conditions are:

Usecode game script (static/eusecode.flx)
This FLX archive contains the game script. Each record corresponds to a class.

Graphics
Ultima 8 uses 256-colour VGA indexed graphics at a 320x200 resolution. Most notable about the resolution for modern concerns is that the pixels were not square, but were instead vertical rectangles. To display them properly on a modern monitor, the graphics should be 20% vertically taller or they will appear crushed. Fortunately the dimetric projection hides quite a bit of this distortion for the world graphics.

Game palette (static/u8pal.pal)
This standalone Palette is used during the game.

Mouse cursors (static/u8mouse.shp)
This standalone Shape file contains the mouse cursors. These are they:

Maps
Ultima 8 uses a 2:1 dimetric perspective. To translate an (X, Y, Z) coordinate in world space to pixels, Xp will be ((X - Y) / S) and Yp will be ((X + Y) / (S * 2) - Z). S is 2 for objects specified in "static/globs.dat" and 4 everywhere else.

World graphics (static/u8shapes.flx)
This FLX archive contains Shapes that fill in the world graphics. The OffsetX and OffsetY fields in the individual shape frames indicate the pixels to subtract from an object's world position to the point to draw the object at.

Map templates (static/globs.dat)
This FLX archive contains blocks of objects that can be inserted into a map to save space. Each record has this format:

World objects (static/fixed.dat, gamedat/nonfixed.dat)
These FLX archives contains the world objects. "static/fixed.dat" contains those objects that cannot be modified during play. "gamedat/nonfixed.dat" contains those objects which can be changed.

Each record contains a Map, which is simply a list of objects. There are as many objects as the (RecordLength / 16). Each object has the format: