Ultima VII internal formats

From Ultima Codex
Jump to navigation Jump to search

This page documents the Ultima VII engine's internal formats.

Data Types and Structure[edit]

Decimal values are given as 123; hexadecimal values are given as 1Fh. All files use little-endian coding. 1122h, for example, is stored as the byte sequence (22h 11h). Signed integers are stored in two's-complement arithmetic. These types are used throughout this document:

  • char - An ASCII character stored as a uint8.
  • uint8/uint16/uint24/uint32 - Unsigned one, two, three, and four-byte integers.
  • int8/int16/int32 - Signed one, two, and four-byte integers.

Files[edit]

This section lists the files in an Ultima VII installation and discusses what is known about them. Further details are found in the File Formats section below. "#" means a single digit (0-9); "*" means any number of any character; "?" means any single character.

  • *.exe - Game executables.
  • game##.u7 - Savegame files.
  • static/ - Contains unchanging game data.
  • gamedat/ - Contains temporary data used during the running of a game.
    • gamedat/action.dat
    • gamedat/av_flags.dat
    • gamedat/flaginit
    • gamedat/frames.flg
    • gamedat/gametim?.dat (where ? is a-m)
    • gamedat/identity
    • gamedat/itemnode.dat
    • gamedat/mapcoord.dat
    • gamedat/misstrac.dat
    • gamedat/party
    • gamedat/path.dat
    • gamedat/path0.dat
    • gamedat/randseed.dat
    • gamedat/u7_ostia.dat
    • gamedat/u7ibuf.dat
    • gamedat/u7ireg?? (where ?? are hexadecimal digits)
    • gamedat/u7nbuf.dat
    • gamedat/weather.dat

Common File Formats[edit]

This section documents file formats that are shared among many different files.

FLX Archives (.flx extension)[edit]

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

Offset Length Format Name Description
00h 80 char[80] Comment An optional comment that can inform the reader about the file. It's not used by the game.
50h 4 uint32 ?? Always FFFF1A00h.
54h 4 uint32 Count The number of records in the file.
58h 4 uint32 ?? Always 0xCC.
5Ch 36 uint32[9] ?? Mostly zeroes.
80h 8*Count Record[Count] Records Offsets and lengths of each record in the archive, described below.
This is the Record type:
00h 4 uint32 Offset Offset of the start of the record data, from the start of the file. If this is zero, there is no record in this slot.
04h 4 uint32 Length Length in bytes of the record data.

Shapes (.shp files and others)[edit]

This describes a graphics image. It is composed of a set of frames, with this header:

Offset Length Format Name Description
00h 4 uint32 Size Size in bytes of the shape file.
04h 4*Count uint32[Count] Offsets Offset of the ShapeFrames relative to the start of the shape. Count is ((Offsets[0] - 4) / 4). So to read the offsets, read the first offset, find out how many items are in the array, and then read the rest.
At each Offset is the ShapeFrame:
00h 2 uint16 MaxX The maximum X value for any span, inclusive.
02h 2 uint16 OffsetX The maximum negative X value for any span. So if this is 80, then no span starts at less than -80 X.
04h 2 uint16 OffsetY The maximum negative Y value for any span. So if this is 40, then no span starts at less than -40 Y.
06h 2 uint16 MaxY The maximum Y value for any span, inclusive.
08h X Spans[...] Spans The list of spans, terminated by a Span with a Data field of zero.
Each Span has this format:
00h 2 uint16 BlockData The type and length of the span. BlockType is (BlockData & 1); BlockLength is (BlockData >> 1). If BlockData zero, then the frame is finished.
02h 2 int16 XStart The horizontal start of the span. This can be negative, but is never less than -OffsetX.
04h 2 int16 YStart The vertical start of the span. This can be negative, but is never less than -OffsetY.
If (Data & 1) is 0, then the span data has this uncompressed format:
06h Length uint8[Length] SpanData Raw pixel data.
If (Data & 1) is 1, then the span data is a run length encoded sequence that runs for as many blocks as needed to consume BlockLength pixels. Each RLE block has this format:
00h 1 uint8 RunData RunType is (RunData & 1); RunLength is (RunData >> 1).
01h X X RunContent If RunType is 0, then this is (uint8[RunLength]) raw pixels. Otherwise this is (uint8 Value), where Value is written out for RunLength pixels.

The total width and height of a frame are (MaxX + OffsetX + 1) and (MaxY + OffsetY + 1) respectively. Here is pseudocode for decoding the RLE data:

while(true) {
    int BlockData = ReadUInt16();
    int BlockLength = BlockData >> 1;
    int BlockType = BlockData & 1;

    if(BlockData == 0)
        break;
    int OffsetX = ReadInt16();
    int OffsetY = ReadInt16();

    if(BlockType == 0)
        ReadImage(OffsetX, OffsetY, BlockLength);
    else {
        int EndX = OffsetX + BlockLength;

        while(OffsetX < EndX) {
            int RunData = ReadUInt8();
            int RunLength = RunData >> 1;
            int RunType = RunData & 1;

            if(RunType == 0)
                ReadImage(OffsetX, OffsetY, RunLength);
            else {
                var Value = ReadUInt8();
                ReadImageRun(OffsetX, OffsetY, RunLength, Value);
            }

            OffsetX += RunLength;
        }
    }
}

ShapeFrameIndex[edit]

This refers to both a shape indexing the archive from the World Shapes section, and a frame within them.

Shift Bits Mask Name Description
0 10 1023 ShapeIndex An index into the "static/shapes.vga" archive. Values below 150/96h are ground tiles; otherwise they are static geometry.
10 5 31 FrameIndex Index of the frame in the shape to use. If the shape is animated (such as shoreline) this is the first frame to use.
15 1 1 ?? ??

File Formats[edit]

This section documents the file formats for specific files.

Game Interface[edit]

This section covers files that deal with the game interface, such as the UI and cursors.

NPC faces (static/faces.vga)[edit]

This Shapes Flx archive contains the NPC faces. Most shapes have a single frame, unless if the NPC has multiple states (like the Avatar being male or female).

Fonts (static/fonts.vga)[edit]

This Shapes Flx archive contains the fonts. Each font contains 128 graphics for the ASCII character set, where empty characters are one pixel wide. Some fonts are "ye olde script", where Latin letters are in the capitals and Runic are in lowercase, with some punctuation used for multi-letter characters.

The fonts are:

Index Description
0 Conversation font in yellow.
1 Carved wood ye olde script.
2 System font in black.
3 Chiselled ye olde script.
4 Book font in black.
5 Book font in white.
6 Gold chiselled ye old script.
8 Conversation font in yellow.

Container and UI images (static/gumps.vga)[edit]

This Shapes Flx archive contains container images and UI graphics. They are:

Index Description
0 Donation box gump.
1 Crate gump.
2 Check and check depressed images.
3 Save game window; each entry has "DISK FULL - USE ANOTHER SLOT" written on it.
4 Save game line backgrounds. First image is for the line, second is for editing it.
5 Load button and load button pushed images.
6 Save button and save button pushed images.
7 Halo off and halo on images.
8 Barrel gump.
9 Bag gump.
10 Backpack gump.
11 Basket gump.
12 Tactics icons - Attack nearest, attack weakest, attack strongest, attack everyone, protect ally, defend, stay at range, run away, do something with everyone, be very confused.
13 Empty.
14 Numeric input window.
15 Numeric input slider button.
16 Numeric input right red and green arrows.
17 Numeric input left red and green arrows.
18-21 Down, up, right, and left arrows on a white background.
22 Chest gump.
23 Monkey paperdoll.
24 Save game button, and pressed.
25 Heart button up and down.
26 Ship's hold gump.
27 Dresser drawer gump.
28 Status icons - sleeping, poisoned, confused, hungry, shield, black dot, snow angel.
29 Music disabled/enabled buttons.
30 Speech disabled/enabled buttons.
31 Sound effects disabled/enabled buttons.
32 Open book window.
33 Awaken, create food, destroy trap, curse, conjure, charm, cause fear, create gold, and Armageddon icons.
34 Weather, cure, enchant, heal, lightning, dance, clone, death bolt, and death vortex icons.
35 Douse, detect trap, fire blast, swarm, mark, dispel field, fire ring, delayed blast, and mass death icons.
36 Fireworks, great douse, great light, protect all, mass curse, explosion, flame strike, energy field, and invisible all icons.
37 Gimmer, great ignite, mass cure, paralyze, recall, great heal, magic storm, energy mist, and resurrect icons.
38 Help, light, protection, peer, reveal, invisibility, poison field, mass charm, and summon icons.
39 Ignite, locate, telekinesis, poison, seance, fire field, sleep field, mass might, and swordstrike icons.
40 Thunder, awaken all, wizard eye, sleep, unlock magic, mass sleep, tremor, restoration, and time stop icons.
41 Page flipping animation.
42 Descending bookmark animation.
43 Spellbook gump.
44 Spellbook turn page left icon.
45 Spellbook turn page right icon.
46 Dove and flaming sword icons.
47 Character information window.
48 Tiny indistinguishable brown lines.
49 Wooden sign window.
50 Gravestone window.
51 Gold plaque window.
52 "Do you want to exit to DOS?", "Are you sure you want to load without saving first?" and "Are you sure you want to save over this old game?" text blocks.
53 Generic dead body gump.
54 Null record.
55 Scroll window.
56 Quit up and down buttons.
57 Male avatar equipment window.
58 Female avatar equipment window.
59 Iolo equipment window.
60 Spark equipment window.
61 Shamino equipment window.
62 Dupre equipment window.
63 Jaana equipment window.
64 Null record.
65 Sentri equipment window.
66 Julia equipment window.
67 Katrina equipment window.
68 Tseramed equipment window.
69 Confirmation window background.
70 Confirmation window yes up and down buttons.
71 Confirmation window no up and down buttons.
72-74 Null records.

Mouse cursors (static/pointers.shp)[edit]

This Shape file contains the mouse cursors. The frames are:

Index Description
0 Finger pointer
1 Red cross
2 Use target (four green arrows pointing inwards)
3 "Too heavy"
4 "Out of range"
5 "Out of ammo"
6 "Won't fit"
7 Hourglass
8-15 Short move arrow north, northeast, east, southeast, south, southwest, west, northwest.
16-23 Medium move arrow north, etc.
24-31 Long move arrow north, etc.
32-39 Short combat arrow north, etc.
40-47 Long combat arrow north, etc.
48 Empty, unused.
49 "Blocked"

Magic effects and miscellaneous graphics (static/sprites.vga)[edit]

This Shape Flx Archive contains magic effects and oddities. These are the shapes in the archive:

Index Description
0 A variety of magic sparkles
1 Huge fireball animation
2 Cloud shadows
3 Smoke animation
4 Medium fireball animation
5 Small fireball animation
6 Eight frames of nothing
7 Sparkles and expanding rings animation
8 Spinning blue death cloud
9 Puff with green sparkles
10 Crystal ball overlay
11 Blood splatter
12 Fireworks
13 Green balls of spinning light
14 Gray squib
15 Multicoloured comets spinning around
16 Mini fireworks
17 Lightning bolt
18 Expanding ring of blue balls
19 Expanding ring of crossbow bolts
20 Null record
21 Purple balls of spinning light
22 Map of Britannia
23 Spinning swords
24 Rising notes
25-29 Null record


World Shapes (static/shapes.vga, static/shpdims.dat, static/wgtvol.dat, static/occlude.dat)[edit]

The world shapes describe the graphics and information about all the objects in the world, excluding some special effects.

"static/shapes.vga" contains the graphical data. "static/shpdims.dat" includes data that are not well understood. "static/wgtvol.dat" includes weight and volume information. "static/tfa.dat" contains flags and type information about shapes.

Graphics Archive (static/shapes.vga)[edit]

This FLX archive file contains the world graphics. From index 0 to 149/95h (inclusive) it contains 8x8 tiles used for the ground, up to 32 per record. From index 150/96h and up it contains Shape records, documented above.

Dimensions (static/shpdims.dat)[edit]

This contains dimensional data for shapes (only shapes index 150/96h and up). It contains a set of (uint8 Vertical, uint8 Horizontal), with this bit format:

Value Shift Bits Mask Name Description
Vertical 0 1 1 BlockVertical? Blocks north-south travel.
Vertical 1 7 127 SizeY? Vertical size of some sort.
Horizontal 0 1 1 BlockHorizontal? Blocks east-west ravel.
Horizontal 1 7 127 SizeX? Horizontal size of some sort.

This file is extremely poorly understood. None of its attributes make particular sense.

Shape Weight/Volume (static/wgtvol.dat)[edit]

This contains weight and volume data for all shapes. It contains a set of (uint8 Weight, uint8 Volume), where Weight is in units of 0.1 stone.

Shape Flags (static/tfa.dat)[edit]

This contains types and flags information for all shapes. It contains a set of (uint24 Bitfield), described below:

Shift Bits Mask Name Description
0 1 1 ?? Exult suggests this is HasSoundEffect, but this includes stalactites and other oddities.
1 1 1 Rotatable Creature that can be rotated from vertical to horizontal to use the same frames, just rotated (sick guy on bed, sea monster, snake).
2 1 1 Animated Animate any object using this shape using the frames of the shape.
3 1 1 NotWalkable Cannot be walked upon, such as a void or person.
4 1 1 Water Can be swum through.
5 3 7 TileSizeZ Height of the shape in tiles.
8 4 15 ShapeType The type of the shape; see below.
12 1 1 Trap Walking into this causes a trap effect - poison, sleep, fire, etc.
13 1 1 Door If set, this is a door.
14 1 1 VehiclePart This tile is part of a vehicle, such as a ship, barge, horse and carriage, and flying carpet.
15 1 1 NotSelectable This cannot be selected, used for light glows and blood splatters.
16 3 7 TileSizeXMinus1 The horizontal width in tiles of the shape minus 1.
19 3 7 TileSizeYMinus1 The vertical height in tiles of the shape minus 1.
22 1 1 LightSource If set, this is a light source.
23 1 1 Translucent If set, frames of this shape use translucent palette indices.

These are the shape type values:

Value Name Description
0 Scenery Unusable scenery objects - trees, ground, etc.
1 Unused Not used by any object (SI not checked).
2 UsesQualiy Objects use the quality field.
3 UsesQuantity Objects use the quantity field.
4 Usable Exult documentation suggests these items are breakable, but it includes looms, paintings, and other items that suggest more that it's for usable objects.
5 QualityFlags The object's quality field is a set of flags.
6 Container Corpses, chess, and desks.
7 ActivateOnApproach Activates on approach - game eggs and sound triggers, blue and red gates.
8 SpellBook Only set for the spellbook.
9 Barge Exult documentation says barge, but this entry (shape 961) is empty.
10 Unused Not used by any objects (SI not checked).
11 VirtueStone Used only on the virtue stones (shape 330).
12 Enemies Enemies that cannot be talked to but can only be fought.
13 Friendlies Creatures that you might be able to talk to.
14 Buildings Some building pieces, walls, carpets, and mountain covers.
15 Unused Not used by any objects (SI not checked).

Shape Occlusion Bit (static/occlude.dat)[edit]

This file contains a bit that can be used to solve some bugs in object sorting. There is one bit for each world shape in ascending order (so the first shape is mask 1, the second shape is mask 2, and so on). This seems to largely be set for walls and ceilings.

Palettes[edit]

This FLX archive file contains the palettes used throughout the game. Each palette has the format (Color[256] Colors), where Color is (uint8 Red, uint8 Green, uint8 Blue), and each component is between 0 and 63. There are 12 palettes in use. Color 255 is transparent.

When not being used for translucent painting, there are six sections of the palette that rotate every 100 milliseconds. At that point, these color ranges move forward. For example, if the color range 252-254 rotate, color 252 takes 254's current value, 253 takes 252's, and 254 takes 253's. The color ranges are:

First index Last index Count
252/FCh 254/FEh 3
248/F8h 251/FBh 4
244/F4h 247/F7h 4
240/F0h 243/F3h 4
232/E8h 239/EFh 8
224/E0h 231/E7h 8

Translucency FLX Archive (static/xform.tbl)[edit]

For world palettes, colours 244/F4h to 254/FEh inclusive are special transparent colours that are used when the Translucent flag is set on a world shape's property. The FLX archive "static/xform.tbl" contains tables to transform an underlying colour into a new colour if the colour being drawn is one of those set. Each entry is (uint8[256] OutputIndices). The table is in reverse order; index 0 is for colour 254, index 1 is for colour 253, and so on.

The equations producing the mapping table are far more complex than simple transparency, and trying to replicate them is made more difficult by the limited palette of colours they had to map to. This table shows the closest matching colours that would produce the same effect that use simple transparency. Each colour value is from 0 (darkest/transparent) to 1 (brightest/opaque).

Index Color Red Green Blue Alpha Notes
0 254/FEh 0.999 0.999 1 0.266 White wash
1 253/FDh 0 0 0 0.251 Shadow
2 252/FCh 1 0.999 0.999 0.463 White frosting
3 251/FBh 1 0.033 0.101 0.327 Red fog
4 250/FAh 0.078 0.304 0 0.545 Green fog
5 249/F9h 0 0.043 1 0.342 Blue binary filter
6 248/F8h 1 0.931 0.19 0.208 Yellow haze
7 247/F7h 0.17 0.59 0 0.341 Green haze with blue patches
8 246/F6h 0.09 0.446 0.734 0.177 Grayscale
9 245/F5h 0.247 0 0 0.251 Reddish
10 244/F4h 0.602 0 0.999 0.228 Purple filter
11 Unused 1 0.003 0.22 0.177 Red filter
12 Unused 0.018 1 0.104 0.444 Green filter
13 Unused 0.593 0.602 1 0.875 Blue filter
14 Unused 0.999 1 0.248 0.79 Yellow filter
15 Unused 0.563 0 0.85 0.342 Purple filter
16 Unused 0.746 0.749 0.749 0.999 Gray wash with white highlights

World Data (static/u7chunks, static/u7map)[edit]

World data are separated into three sections: ground, fixed objects, and regular objects.

The ground tiles are a series of 8x8 pixel tiles that constitute the floor. Those are grouped into 16x16 chunks, along with static geometry. These template Chunks are referenced by 16x16 Regions, and there are 12x12 Regions in the world map.

Chunk Templates (static/u7chunks)[edit]

This file contains a list of chunk templates that are then indexed by the regions.

Offset Length Type Name Description
00h X*512 Chunk[X] Chunks The list of chunks. There are as many chunks as there is space in the file; Ultima 7 comes with 3072/C00h.
Each Chunk has the format:
00h 512 ShapeFrameIndex[16 * 16] Tiles Tiles in the chunk in [x + y * 16] order.

A shape index refers to both tiles and shapes. The shape should be inserted into the world as static geometry at zero height.

Static Chunk Data (static/u7map)[edit]

This file contains the chunks for the static map. The map is partitioned into (Region[12 * 12] Regions) (in [x + y * 12] order), where Region is (uint16[16 * 16] Chunks), where each value is an index into "static/u7chunks" described above.

Fixed Items Data (static/u7ifix??)[edit]

These files contain the fixed objects for the region. They are named as u7ifixXX, where XX is a hexadecimal number that is (RegionX + RegionY * 12).

Within the FLX Archive files are 16*16 records for each chunk in the region in [ChunkX + ChunkY * 16] order. If an entry is empty, it contains no fixed objects. Otherwise it contains a list of (uint16 Bitfield, ShapeFrameIndex ShapeFrame), where the bitfield described below:

Shift Bits Mask Name Description
0 4 15 Y Y coordinate inside the chunk.
4 4 15 X X coordinate inside the chunk.
8 4 15 Z Height level.
12 4 15 ?? Always zero.

References[edit]


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